导致死锁的原因
多个线程同时被阻塞,它们中的一个或者全部都在等待某个资源被释放,而该资源又被其他线程锁定,
从而导致每一个线程都得等其它线程释放其锁定的资源,造成了所有线程都无法正常结束。
死锁产生的四个必要条件:
- 互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用
- 不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放
- 请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有
- 循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P1的资源,这样就形成了一个等待环路
1.1 模拟两个资源
package com.practice; public class ThreadResource { public static Object resourceA = new Object(); public static Object resourceB= new Object(); }
1.2 模拟线程A占用资源A并申请获得资源B的锁
package com.practice; public class ThreadA implements Runnable { @Override public void run() { try { System.out.println("ThreadA is running"); synchronized (ThreadResource.resourceA) { System.out.println("ThreadA lock resourceA"); Thread.sleep(2000);// 休眠2s等待线程2锁定资源2 synchronized (ThreadResource.resourceB) { System.out.println("ThreadA lock resourceB"); } System.out.println("ThreadA release resourceB"); } System.out.println("ThreadA release resourceA"); } catch (Exception e) { System.out.println(e.getMessage()); } System.out.println("ThreadA is stop"); } }
1.3 模拟线程B占用资源B并申请获得资源A的锁
package com.practice; public class ThreadB implements Runnable { @Override public void run() { try { System.out.println("ThreadB is running"); synchronized (ThreadResource.resourceB) { System.out.println("ThreadB lock resourceB"); Thread.sleep(2000);// 休眠2s等待线程1锁定资源1 synchronized (ThreadResource.resourceA) { System.out.println("ThreadB lock resourceA"); } System.out.println("ThreadB release resourceA"); } System.out.println("ThreadB release resourceB"); } catch (Exception e) { System.out.println(e.getMessage()); } System.out.println("Thread2 is stop"); } }
1.4 同时运行俩个线程
package com.practice; public class TestDeadLock { public static void main(String[] args) { new Thread(new ThreadA()).start(); new Thread(new ThreadB()).start(); } }