zoukankan      html  css  js  c++  java
  • 多线程之——死锁

    一、何为死锁

    采用多线程是为了改善系统资源的利用并提高系统的处理能力。然而,在实际使用过程中,会遇到新的问题——死锁。所谓死锁,就是多个线程因为资源竞争而造成的一种互相等待的状态,若无外力作用,这种状态会一直维持。

    二、死锁的原因

    举个死锁产生的例子:

     1 /**  
     2 * 一个简单的死锁类  
     3 * 当DeadLock类的对象flag==1时(td1),先锁定o1,睡眠500毫秒  
     4 * 而td1在睡眠的时候另一个flag==0的对象(td2)线程启动,先锁定o2,睡眠500毫秒  
     5 * td1睡眠结束后需要锁定o2才能继续执行,而此时o2已被td2锁定;  
     6 * td2睡眠结束后需要锁定o1才能继续执行,而此时o1已被td1锁定;  
     7 * td1、td2相互等待,都需要得到对方锁定的资源才能继续执行,从而死锁。  
     8 */    
     9 public class DeadLock implements Runnable {    
    10     public int flag = 1;    
    11     //静态对象是类的所有对象共享的    
    12     private static Object o1 = new Object(), o2 = new Object();    
    13     @Override    
    14     public void run() {    
    15         System.out.println("flag=" + flag);    
    16         if (flag == 1) {    
    17             synchronized (o1) {    
    18                 try {    
    19                     Thread.sleep(500);    
    20                 } catch (Exception e) {    
    21                     e.printStackTrace();    
    22                 }    
    23                 synchronized (o2) {    
    24                     System.out.println("1");    
    25                 }    
    26             }    
    27         }    
    28         if (flag == 0) {    
    29             synchronized (o2) {    
    30                 try {    
    31                     Thread.sleep(500);    
    32                 } catch (Exception e) {    
    33                     e.printStackTrace();    
    34                 }    
    35                 synchronized (o1) {    
    36                     System.out.println("0");    
    37                 }    
    38             }    
    39         }    
    40     }    
    41     
    42     public static void main(String[] args) {    
    43             
    44         DeadLock td1 = new DeadLock();    
    45         DeadLock td2 = new DeadLock();    
    46         td1.flag = 1;    
    47         td2.flag = 0;    
    48         //td1,td2都处于可执行状态,但JVM线程调度先执行哪个线程是不确定的。    
    49         //td2的run()可能在td1的run()之前运行    
    50         new Thread(td1).start();    
    51         new Thread(td2).start();    
    52     
    53     }    
    54 }    

    三、如何避免死锁

    1.加锁顺序(线程按照一定的顺序加锁)

    2.加锁时限(线程在尝试获取锁的时候加上一定的时限,超期则放弃该次请求,并释放自己占有的锁)

    3.死锁检测

  • 相关阅读:
    转载:史上最全|阿里那些牛逼带闪电的开源工具,你知道几个?
    互怼、IPO、雷潮、寒冬,2018 互联网圈的那些事儿
    微信迎来又一次重大改版 7.0 版本
    公众号文章目录
    聊几个与赚钱相关的小事情
    使用docker Registry快速搭建私有镜像仓库
    开源组件ELK日志系统配置与管理
    Mysql MHA高可用集群架构
    强大的开源企业级数据监控利器Lepus安装与配置管理
    关于下载gitbash客户端
  • 原文地址:https://www.cnblogs.com/zyxiaohuihui/p/9112401.html
Copyright © 2011-2022 走看看