文章目录

  • 死锁
  • 互斥条件
  • 不可剥夺条件
  • 请求与保持条件
  • 循环等待条件
  • 如何避免死锁
  • 如何检测死锁
  • Jconsole查看死锁

死锁

  • Java中当我们的开发涉及到多线程的时候,这个时候就很容易遇到死锁问题
  • 首先了解一下死锁的四个必要条件

互斥条件

进程要求对所分配的资源(如打印机)进行排他性控制,即在一段时间内某资源仅为一个进程所占有。此时若有其他进程请求该资源,则请求进程只能等待。

不可剥夺条件

进程所获得的资源在未使用完毕之前,不能被其他进程强行夺走,即只能由获得该资源的进程自己来释放(只能是主动释放)。

请求与保持条件

进程已经保持了至少一个资源,但又提出了新的资源请求,而该资源已被其他进程占有,此时请求进程被阻塞,但对自己已获得的资源保持不放。

循环等待条件

存在一种进程资源的循环等待链,链中每一个进程已获得的资源同时被 链中下一个进程所请求。即存在一个处于等待状态的进程集合{Pl, P2, …, pn},其中Pi等 待的资源被P(i+1)占有(i=0, 1, …, n-1),Pn等待的资源被P0占有

java如何判断对象是否加锁了_java

以上这四个条件是死锁的必要条件,只要系统发生死锁,这些条件必然成立,而只要上述条件之一不满足,就不会发生死锁。

  • 死锁产生原因:当两个或者多个线程互相持有一定资源,并互相等待其他线程释放资源而形成的一种僵局,就是死锁。

如何避免死锁

  1. 死锁的根本的多线程, 多线程下就会有资源的线程安全问题, 就必须使用同步代码块, 使用同步代码块就会有死锁的风险, 所以避免死锁的核心是资源,我们使用可消耗资源和可竞争资源代替原有资源, 但是这个有时候并不能实现, 因为实际情况在那
  2. 使用ReentrantLock.trylock代替synchronize的
  3. 使用CAS代替synchronized
  4. 避免在一个同步代码块中去竞争其他锁资源

如何检测死锁

  • Java中jdk 给我们提供了很便利的工具,帮助我们定位和分析死锁问题:
  • 构建一个死锁的场景:
public class Test {
 
	public static void main(String[] args) {
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				synchronized (B.class) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						e.printStackTrace();
					}
					synchronized (A.class) {
						
					}
				}
			}
		}).start();
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				synchronized (A.class) {
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					synchronized (B.class) {
						
					}
				}
				
			}
		}).start();
	}
	
}
class A {
	
}
 
class B {
	
}

可以看到运行时,一个线程持有A资源,希望使用B资源,而另一个线程持有B资源,希望使用A 资源,然后就陷入了相互等待的僵局,这样就形成了死锁。

Jconsole查看死锁

进入java安装的位置,输入Jconsole,然后弹出界面(或者进入安装目录/java/jdk1.70_80/bin/,点击Jconsole.exe):

java如何判断对象是否加锁了_并发编程_02


然后点击进入:

java如何判断对象是否加锁了_死锁_03


然后点击检测死锁:

然后可以看到造成死锁的两个线程,以及死锁原因:

java如何判断对象是否加锁了_死锁_04


java如何判断对象是否加锁了_死锁_05

Thread-0:持有java.lang.Class@1694ce18,需要java.lang.Class@1feb0edd,但是java.lang.Class@1feb0edd却被Thread-1持有,然后陷入等待。