[Java] DeadLock(死锁)的示例

电脑杂谈  发布时间:2020-06-07 14:17:33  来源:网络整理

并发程序 死锁_银行家算法避免死锁_死锁举例

我今天参加了InteliJ并模拟了一个僵局.

由synced关键字修改的方法可能会导致死锁. (同步只能修改方法,就像volatile只能修改变量一样. )

简单介绍. 出现以下死锁的原因是,A线程需要获取lock1和lock2以便分别打印句子,而B线程需要获取lock2和lock1以便分别打印句子. 这两个线程是异步的. 在执行过程中,有两种情况:

并发程序 死锁_死锁举例_银行家算法避免死锁

方案1:

一个快速保持的锁1,保持的锁2,释放的锁2,释放的锁1,并成功打印了两个句子.

然后B按住lock2,按住lock1,释放l​​ock1,释放l​​ock2,并成功打印两个句子.

银行家算法避免死锁_死锁举例_并发程序 死锁

情况2:

A持有lock1并打印第一句(不释放lock1),这时B持有lock2并打印第一句;那么A想要持有lock2并等待B释放lock2,但是lock2无法释放,因为如果要释放lock2,则它必须首先获取lock1并执行任务.

请注意,这两个锁必须嵌套并调用.

死锁举例_并发程序 死锁_银行家算法避免死锁

看代码更容易理解:

public class TestDeadLock {
    
    public void run() {
        MyThread mt = new MyThread();
        new Thread(mt, "张三").start();
        new Thread(mt, "李四").start();
    }
    
    class MyThread implements Runnable {
        //lock要写成final的,否则如果lock指向变了,锁就失效了
        private final Object mLock1 = new Object();
        private final Object mLock2 = new Object();
        //boolean用来确保两个线程获得不同的锁。
        private boolean flag = true;
        
        @Override
        public void run() {
            if (flag) {
                flag = false;
                //注意,两把锁一要嵌套调用
                synchronized (mLock1) {
                    System.out.println(Thread.currentThread().getName() + " have mLock1");
//                  try {
//                      Thread.sleep(100);
//                  } catch (InterruptedException e) {
//                      e.printStackTrace();
//                  }
                    synchronized (mLock2) {
                        System.out.println(Thread.currentThread().getName() + " have mLock2");
                    }
                }
            } else {
                flag = true;
                synchronized (mLock2) {
                    System.out.println(Thread.currentThread().getName() + " have mLock2");
//                  try {
//                      Thread.sleep(100);
//                  } catch (InterruptedException e) {
//                      e.printStackTrace();
//                  }
                    synchronized (mLock1) {
                        System.out.println(Thread.currentThread().getName() + " have mLock1");
                    }
                }
            }
        }
    }
    
    public static void main(String[] args) {
        new TestDeadLock().run();
    }
}

我删除了睡眠部分,因此由于线程抢占了CPU资源,因此每次执行的结果将有所不同(上述两种情况).

并发程序 死锁_死锁举例_银行家算法避免死锁

下面的屏幕快照对应第一种情况:

image.png

下面的屏幕截图对应于第二种情况. 它被卡在这里死锁举例,并发生了死锁:

image.png

然后死锁举例,如果您放弃睡眠注释,就会发生第二种情况.

参考:

©版权归作者所有,如需转载或内容合作,请联系作者


本文来自电脑杂谈,转载请注明本文网址:
https://www.pc-fly.com/a/jisuanjixue/article-237260-1.html

    相关阅读
      发表评论  请自觉遵守互联网相关的政策法规,严禁发布、暴力、反动的言论

      热点图片
      拼命载入中...