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.死锁检测

  • 相关阅读:
    Attributes in C#
    asp.net C# 时间格式大全
    UVA 10518 How Many Calls?
    UVA 10303 How Many Trees?
    UVA 991 Safe Salutations
    UVA 10862 Connect the Cable Wires
    UVA 10417 Gift Exchanging
    UVA 10229 Modular Fibonacci
    UVA 10079 Pizza Cutting
    UVA 10334 Ray Through Glasses
  • 原文地址:https://www.cnblogs.com/zyxiaohuihui/p/9112401.html
Copyright © 2011-2022 走看看