zoukankan      html  css  js  c++  java
  • 线程死锁问题

    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 + "	flag = " + 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、预防线程死锁应该遵循的原则:

    • 尽量的减少同步资源的定义
    • 尽量避免嵌套同步
    • 采用专门的算法、原则
  • 相关阅读:
    安装pipenv
    ModuleNotFoundError: No module named 'pip._internal' , pip 无法下载软件 解决办法
    1.3用户列表 and 新闻列表
    1.2用户统计页面实现
    1.5发布新闻
    七牛云平台(存储图片)
    1.2头像设置功能
    1.4用户收藏展示
    1.3密码修改
    1.2首页刷新以及点击排行
  • 原文地址:https://www.cnblogs.com/BaoZiY/p/10727158.html
Copyright © 2011-2022 走看看