• 什么是死锁?


    线程死锁是指由于两个或者多个线程互相持有所需要的资源,导致这些线程一直处于等待其他线程释放资源的状态,无法前往执行,如果线程都不主动释放所占有的资源,将产生死锁。

    当线程处于这种僵持状态时,若无外力作用,它们都将无法再向前推进。

    产生原因:

    • 持有系统不可剥夺资源,去竞争其他已被占用的系统不可剥夺资源,形成程序僵死的竞争关系。
    • 持有资源的锁,去竞争锁已被占用的其他资源,形成程序僵死的争关系。
    • 信号量使用不当。

    ...

    如线程A占有资源 1 的锁,去竞争资源 2 的锁;线程 B 占有资源 2 的锁,去竞争资源1的锁。

    代码表现如下

    package constxiong.concurrency.a022;
    
    /**
     * 测试死锁
     * @author ConstXiong
     * @date 2019-09-23 19:28:23
     */
    public class TestDeadLock {
         
        final static Object o1 = new Object();
        
        final static Object o2 = new Object();
        
        public static void main(String[] args) {
            //先持有 o1 的锁,再去获取 o2 的锁
            Thread t1 = new Thread() {
                
                @Override
                public void run() {
                    synchronized (o1) {
                        System.out.println("线程:" + Thread.currentThread().getName() + " 获取到 o1 对象的锁");
                        try {
                            System.out.println("休眠1秒");
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        
                        System.out.println("线程:" + Thread.currentThread().getName() + " 去获取 o2 对象的锁");
                        synchronized (o2) {
                            System.out.println("线程:" + Thread.currentThread().getName() + " 成功获取 o2 对象的锁");
                        }
                    }
                }
                
            };
            
            //先持有 o2 的锁,再去获取 o1 的锁
            Thread t2 = new Thread() {
                
                @Override
                public void run() {
                    synchronized (o2) {
                        System.out.println("线程:" + Thread.currentThread().getName() + " 获取到 o2 对象的锁");
                        try {
                            System.out.println("休眠1秒");
                            Thread.sleep(1000);
                        } catch (InterruptedException e) {
                            e.printStackTrace();
                        }
                        
                        System.out.println("线程:" + Thread.currentThread().getName() + " 去获取 o1 对象的锁");
                        synchronized (o1) {
                            System.out.println("线程:" + Thread.currentThread().getName() + " 成功获取 o1 对象的锁");
                        }
                    }
                }
                
            };
            
            
            t1.start();
            t2.start();
        }
        
    }

    测试结果,发生死锁,打印如下

    线程:Thread-0 获取到 o1 对象的锁
    休眠1秒
    线程:Thread-1 获取到 o2 对象的锁
    休眠1秒
    线程:Thread-1 去获取 o1 对象的锁
    线程:Thread-0 去获取 o2 对象的锁


     


     

    所有资源资源汇总于公众号



     

  • 相关阅读:
    菜鸟看懂算法以后之一:头痛的64次左移
    C语言通过指针数组和二维数组读取文件
    C++中构造函数调用构造函数
    bnuoj53075 外挂使用拒绝
    [CodeForces]String Reconstruction
    BNU-2017.7.4排位赛2总结
    BNU-2017.7.5排位赛3总结
    BNU-2017.7.3排位赛1总结
    微软大楼设计方案(困难)
    最长公共子序列针对小字符集的算法
  • 原文地址:https://www.cnblogs.com/ConstXiong/p/11976060.html
Copyright © 2020-2023  润新知