java 死锁例子以及闭锁使用确保死锁产生

今天在参悟他人面经过程中发现一个“简单”的问题:编写一个死锁的代码实例。

看到这个问题,被一个个“高深”的问题虐的怀疑人生的我立马撸了一个java死锁的例子。

 1 public class Deadlock {
 2     
 3     //两个被锁的元素
 4     private Object l = new Object();
 5     private Object r = new Object();
 6     
 7     //两种相反的加锁顺序
 8     public void lrLock(){
 9         synchronized (l) {
10             System.out.println("lrLock lock l");
11             try {
12                 Thread.sleep(2500);//sleep不释放锁,让当前线程进入TIMED_WAITING状态,尽量使另一个线程把r资源锁住
13             } catch (InterruptedException e) {
14                 e.printStackTrace();
15             }
16             synchronized (r) {
17                 System.out.println("lrLock lock r----no dead lock");
18             }
19         }
20     }
21     
22     public void rlLock(){
23         synchronized (r) {
24             try {
25                 Thread.sleep(500);
26             } catch (InterruptedException e) {
27                 e.printStackTrace();
28             }
29             System.out.println("rlLock lock r");
30             synchronized (l) {
31                 System.out.println("rlLock lock l----no dead lock");
32             }
33         }
34     }
35 }

 再来一段main方法调用该实例

 1 public static void main(String[] args) {
 2     
 3     Deadlock deadlock = new Deadlock();
 4     Thread threadA = new Thread(new Runnable() {
 5         public void run() {
 6             deadlock.lrLock();
 7         }
 8     });
 9     Thread threadB = new Thread(new Runnable() {
10         public void run() {
11             deadlock.rlLock();
12         }
13     });
14     
15     threadA.start();
16     threadB.start();
17 }

 

啊哈,这个送分题还不是分分钟被我解决了~吗???等等,运行怎么没产生死锁?

怎么运行是这个玩意儿?我可爱的死锁嘞?我还特意的用sleep方法让第二个线程上锁的机会增加呢,可,莫非是我脸黑?再来一次,还是没出现死锁,再来亿次!还是没有。

陷入沉思的我,这,我菜到连一个死锁都写不出来了嘛,莫非,莫非是虚拟机运行时用了自旋锁优化?对!一定是这样(自旋锁其实针对的是同一个资源的锁,和这个例子并没有太大的联系)。

就在我自以为找到了原因之时,再一次的运行秒打了我的脸,原来之前只是脸不好没运行出死锁的情况而已。

这就很尴尬了呀,难道我打的代码还要看机器的心情而不能按照我的意愿来,想让他死锁就死锁嘛?

一番思考之后,我把代码改成了下面那样。

public class Deadlock {
    
    private Object l = new Object();
    private Object r = new Object();
    //用闭锁保证一个线程锁住l资源,另一个线程锁住r资源
    private CountDownLatch latch = new CountDownLatch(2);
    
    public void lrLock(){
        synchronized (l) {
            latch.countDown();
            System.out.println("lrLock lock l");
            try {
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (r) {
                System.out.println("lrLock lock r----no dead lock");
            }
        }
    }
    
    public void rlLock(){
        synchronized (r) {
            System.out.println("rlLock lock r");
            latch.countDown();
            try {
                latch.await();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            synchronized (l) {
                System.out.println("rlLock lock l----no dead lock");
            }
        }
    }
}

 

闭锁的使用,保证A线程能锁住l资源并且A线程请求r资源前B线程已经把r资源锁住导致死锁的产生。

啊哈,这下我可以想运行出死锁就运行出来了。

舒服了,收工!

 

posted @ 2018-05-14 00:48  zhangdapao  阅读(248)  评论(0编辑  收藏  举报