• 什么是死锁?


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

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

    产生原因:

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

    ...

    如线程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的面试题?

  • 相关阅读:
    随机变量与概率分布
    概率知识归纳
    随机生成&部门匹配
    SudokuGame 记软工第二次作业
    从0到1的开发,社交App 完成
    Emmm,从删库到跑路系列之.......Root权限的重要性
    处理AsyncTask的内存泄漏问题
    关于服务器端的Json文件的接收,踩了一早上的坑的问题
    一些安卓模拟器的IP问题和getOutputStream();关于connect();的函数异常的问题
    擦擦博客的灰------开始毕设,社交应用开发 之 前期准备
  • 原文地址:https://www.cnblogs.com/ConstXiong/p/11687984.html
Copyright © 2020-2023  润新知