概念解析-死锁&饥饿&活锁
发布日期:2021-09-25 11:48:20 浏览次数:9 分类:技术文章

本文共 1659 字,大约阅读时间需要 5 分钟。

1.死锁:通俗地说,死锁是两个或者多个线程,相互占用对方需要的资源,而都不进行释放,导致彼此之间都相互等待对方释放资源,产生了无限制等待的现象,死锁一旦发生,如果没有外力介入,这种等待将永远存在,从而对程序产生严重的影响

用来描述死锁的一个有名的场景是“哲学家就餐”问题,用一个简单的例子来模拟下,有两个科学家和两把叉子

package LockTest;public class DeadLock extends Thread{	protected Object tool;	static Object fork1=new Object();    static Object fork2=new Object();    public DeadLock(Object obj){    	this.tool=obj;    	if(tool==fork1){    		this.setName("哲学家A");    	}    	else if(tool==fork2){    		this.setName("哲学家B");    	}    }        public void run(){    	if(tool==fork1){    		synchronized(fork1){    			try{    				Thread.sleep(500);    			}catch(Exception e){    				e.printStackTrace();    			}    			synchronized(fork2){    				System.out.println("哲学家A开始吃饭了");    			}    		}    	}    	if(tool==fork2){    		synchronized(fork2){    			try{    				Thread.sleep(500);    			}catch(Exception e){    				e.printStackTrace();    			}    			synchronized(fork1){    				System.out.println("哲学家B开始吃饭了");    			}    		}    	}    }    	public static void main(String[] args) throws InterruptedException {		// TODO Auto-generated method stub		DeadLock PhilosopherA=new DeadLock(fork1);		DeadLock PhilosopherB=new DeadLock(fork2);		PhilosopherA.start();		PhilosopherB.start();		Thread.sleep(1000);	}}

哲学家A先占用叉子1,哲学家B占用叉子2,接着他们就相互等待,都没有办法同时获得两个叉子用餐。实际环境中,遇到了这种情况,通常的表现就是相关的进程不再工作,并且CPU占用率为0(因为死锁的线程不占用CPU),可以使用JDK确认问题:使用jps命令得到java进程的进程ID,接着使用jstack命令得到线程的线程堆栈:

找到了死锁的存在,并在最后可以看出两者互相等待的锁的ID

2.饥饿

某一个或者多个线程因为种种原因无法获得所需要的资源,导致一直无法执行,比如它的线程优先级可能太低,而高优先级的线程不断抢占它需要的资源,导致低优先级线程无法工作。与死锁相比,饥饿还是有可能在未来一段时间内解决的,比如高优先级的线程已经完成任务,不再疯狂地执行

3.活锁

任务或者执行者没有被阻塞,由于某些条件没有满足,导致一直重复尝试、失败、尝试、失败。活锁和死锁的区别在于,处于活锁的实体时在不断改变状态,活锁有可能自行解开而死锁不能

转载地址:https://blog.csdn.net/Autumn03/article/details/80928942 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:锁的优化
下一篇:源码分析-Java Map

发表评论

最新留言

留言是一种美德,欢迎回访!
[***.207.175.100]2024年04月02日 05时12分58秒