• 什么是死锁?


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

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

    产生原因:

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

    ...

    如线程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 对象的锁

     来一道刷了进BAT的面试题?

  • 相关阅读:
    clientHeight和offsetHeight
    bus事件总线传值
    解决英文溢出不换行
    小程序熏染可滑动动态导航
    个人样式小结
    数组删除元素
    vue封装swiper
    大佬的接口玩玩
    Java探针技术-JVM的动态agent机制:在main函数启动之后运行agent
    Java探针技术-Instrumentation与ClassFileTransformer--字节码转换工具
  • 原文地址:https://www.cnblogs.com/ConstXiong/p/11687984.html
Copyright © 2020-2023  润新知