死锁的简单实现
死锁的四个必要条件:
1. 互斥:资源不能多线程共享
2. 不剥夺:线程不能强行剥夺其他线程持有的资源
3. 请求与保持:线程请求它所需要的资源时,继续保持自己已持有的资源
4. 环路等待:这个比较容易理解,多个线程的请求之间形成了一个环路。如果不理解,请看下面一个段子:
【女儿】:妈妈,明早我要考试,5点钟一定要叫醒我。
【女主】:好的。
【女主】:老公,明早5点之前一定叫醒我
【男主】:好的,刚好明早我要晨练
【男主】:女儿,明早我要晨练,5点之前叫醒我。
【女儿】:没问题,我明早要考试,肯定能起来。
上面就形成了环路等待,于是一家三口睡到了自然醒。。。
废话不多说,下面给出一个很简单的死锁的代码实现:
线程-1 持有了A锁,线程-2持有了B锁,然后线程-1请求B锁,线程2请求A锁,这样就形成了死锁。
代码如下:
package thread; public class DeadLock { public static void main(String[] args) { Object lock1 = new Object(); Object lock2 = new Object(); Mt1 mt1 = new Mt1(lock1, lock2); Mt2 mt2 = new Mt2(lock1, lock2); mt1.start(); mt2.start(); } } class Mt1 extends Thread { Object s1 ; Object s2 ; public Mt1(Object lock1,Object lock2){ this.s1 = lock1; this.s2 = lock2; } public void run() { try { synchronized (s1) { System.out.println("get lock1"); sleep(300);//持有了S1锁,并将自己挂起0.3秒,然后请求S2锁 synchronized (s2) { System.out.println("get lock2"); } } } catch (Exception e) { } } } class Mt2 extends Thread{ Object s1 ; Object s2 ; public Mt2(Object lock1,Object lock2){ this.s1 = lock1; this.s2 = lock2; } public void run() { try { synchronized (s2) { System.out.println("get lock2");//线程1将自己挂起的0.3秒内,线程2抢到了S2锁,并试图申请s1锁(此时S1锁已经被线程1持有,因此线程2挂起)synchronized (s1) { System.out.println("get lock1"); } } } catch (Exception e) { } } }