zoukankan      html  css  js  c++  java
  • 什么是死锁?

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

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

    产生原因:

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

    ...

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


     


     

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



     

  • 相关阅读:
    转char varchar nvarchar区别
    NHibernate和Spring.Net框架介绍(一)
    ASP.NET面试题(一)
    存储过程编写经验和优化措施
    软件工程师不可不知的10个概念
    优化数据库前问自己的10个问题
    ZOJ 1610 Count the Colors (线段树)
    POJ 3667 Hotel (线段树)
    HDU Best Reward (扩展KMP)
    POJ 3277 City Horizon (线段树)
  • 原文地址:https://www.cnblogs.com/ConstXiong/p/11976060.html
Copyright © 2011-2022 走看看