首页 > 编程语言 > 详细

线程死锁问题

时间:2019-04-19 13:06:44      阅读:107      评论:0      收藏:0      [点我收藏+]

1、线程死锁产生的原因:

  • 不同的线程分别占用对方需要的同步资源不放弃,都在等待对方放弃自己需要的同步资源,这样就会造成线程的死锁问题

  • 出现线程死锁之后,程序不会报异常,不会出现提示,只是所有的线程都处于阻塞状态,无法继续执行
  • 死锁产生的四个必要条件
    • 互斥使用,即当资源被一个线程使用(占有)时,别的线程不能使用
    • 不可抢占,资源请求者不能强制从资源占有者手中夺取资源,资源只能由资源占有者主动释放。
    • 请求和保持,即当资源请求者在请求其他的资源的同时保持对原有资源的占有。
    • 循环等待,即存在一个等待队列:P1占有P2的资源,P2占有P3的资源,P3占有P1的资源。这样就形成了一个等待环路。
  • 当上述四个条件都成立的时候,便形成死锁。当然,死锁的情况下如果打破上述任何一个条件,便可让死锁消失。

2、线程死锁的代码实例:

 1 package com.baozi.thread;
 2 
 3 /**
 4  * 用两个线程请求被对方占用的资源,实现线程死锁
 5  * 
 6  * 
 7  */
 8 public class DeadLockThread implements Runnable {
 9     private static final Object objectA = new Object();
10     private static final Object objectB = new Object();
11     private boolean flag;
12 
13     @Override
14     public void run() {
15         String threadName = Thread.currentThread().getName();
16         System.out.println("当前线程 为:" + threadName + "\tflag = " + flag);
17         if (flag) {
18             synchronized (objectA) {
19                 try {
20                     Thread.sleep(1000);
21                 } catch (InterruptedException e) {
22                     // TODO Auto-generated catch block
23                     e.printStackTrace();
24                 }
25                 System.out.println(threadName + "已进入同步代码块objectA,准备进入objectB");
26                 synchronized (objectB) {
27                     System.out.println(threadName + "已经进入同步代码块objectB");
28                 }
29             }
30 
31         } else {
32             synchronized (objectB) {
33                 try {
34                     Thread.sleep(1000);
35                 } catch (InterruptedException e) {
36                     // TODO Auto-generated catch block
37                     e.printStackTrace();
38                 }
39                 System.out.println(threadName + "已进入同步代码块objectB,准备进入objectA");
40                 synchronized (objectA) {
41                     System.out.println(threadName + "已经进入同步代码块objectA");
42                 }
43             }
44         }
45     }
46 
47     public static void main(String[] args) {
48         DeadLockThread deadlock1 = new DeadLockThread();
49         DeadLockThread deadlock2 = new DeadLockThread();
50         deadlock1.flag = true;
51         deadlock2.flag = false;
52         Thread thread1 = new Thread(deadlock1);
53         Thread thread2 = new Thread(deadlock2);
54         thread1.start();
55         thread2.start();
56 
57     }
58 
59 }

3、解决方法

要预防和避免死锁的发生,只需将上面所讲到的4个条件破坏掉其中之一即可。

如上面的代码当中,由于有四个同步代码块,代表着线程要占用的资源,只需要将其中一个同步代码块去掉,即可解决死锁问题。

一般而言破坏“循环等待”这个条件是解决死锁最有效的方法

4、预防线程死锁应该遵循的原则:

  • 尽量的减少同步资源的定义
  • 尽量避免嵌套同步
  • 采用专门的算法、原则

 

线程死锁问题

原文:https://www.cnblogs.com/BaoZiY/p/10727158.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!