JAVA多线程学习系列 - 死锁

定义两个或两个以上的进程在执行过程中,由于竞争资源或者由于彼此通信而造成的一种阻塞或互相等待的现象。

数据流转图


如上图 : 

线程A先去获取锁资源Lock1,停留3秒,再去获取Lock2,  此时线程A占用的Lock1未释放 。

与此同时,ThreadB先去获取Lock2,停留3秒,再去获取Lock1, 此时线程B占用的Lock2未释放。

造成的结果:  ThreadA 等待ThreadB释放Lock2,  而ThreadB也在等待ThreadA释放Lock1,互相等待,造成了死锁。


用Java程序描述上面流程关系:

public class DeadThread {

	// 对象锁1
	private static volatile Object lock1 = new Object();
	// 对象锁2
	private static volatile Object lock2 = new Object();

	public static void main(String[] args) {
		Thread threadA = new Thread(new ThreadA(),"Thread A ");
		threadA.start();
		Thread threadB = new Thread(new ThreadB(),"Thread B ");
		threadB.start();
	}

	static class ThreadA extends Thread {
		@Override
		public void run() {
			String threadName = Thread.currentThread().getName();
			System.out.println(threadName + "try get lock 1");
			synchronized (lock1) {
				System.out.println(threadName + "get lock 1");
				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(threadName + "try to get lock 2");

				synchronized (lock2) {
					System.out.println(threadName + " get lock 2");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println(threadName + " release lock 2");

				}
				System.out.println(threadName + " release lock 1");

			}
		}
	}

	static class ThreadB extends Thread {
		@Override
		public void run() {
			String threadName = Thread.currentThread().getName();

			System.out.println(threadName + "try get lock 2");
			synchronized (lock2) {
				System.out.println(threadName + "get lock 2");
				try {
					Thread.sleep(3000);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}
				System.out.println(threadName + "try to get lock 1");

				synchronized (lock1) {
					System.out.println(threadName + " get lock 1");
					try {
						Thread.sleep(1000);
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
					System.out.println(threadName + " release lock 1");

				}
				System.out.println(threadName + " release lock 2");
				
			}
		}
	}
}

打印结果:



可以看到,线程A一直试图获取 lock 2 ,线程B也一直试图获取 lock1


我们再去打开VisualVm去监控死锁的情况 : Deadlock detected,死锁被检测到。


再用ThreadDump分析下



可以看到ThreadA和 ThreadB 的Thread State 都是出于Blocked的状态,

ThreadB 

        - waiting to lock <0x00000000d5efb020> (a java.lang.Object) ,其中0x00000000d5efb020即为锁资源Lock1

ThreadA 

       - waiting to lock <0x00000000d5efb030> (a java.lang.Object) ,  其中0x00000000d5efb030即为锁资源Lock2









猜你喜欢

转载自blog.csdn.net/weixin_42443023/article/details/80665526
今日推荐