• 多线程17:死锁


    死锁:
    • 多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致两个或者多个线程都在等待对方释放资源,都停止执行的情形。某一个同步块同时拥有"两个以上对象的锁"时,就可能会发生"死锁"的问题。
     
    思路:
    1. 首先要有两个对象口红 Lipstick 类 和镜子 Mirror 类
    2. 然后需要一件事情,比如都要去化妆 Makeup 类继承一下Thread类重写run方法,只有一份资源(用static保证只有一份),一个口红一个镜子。
    3. 我呢,先拿到了口红,你呢,你先拿了镜子。
    4. 1秒钟以后我想拿镜子,2秒后你想拿口红,于是你们两互相僵持,不想给对方。
    5. 于是启动线程后,发现程序卡死了。
    6. 然后解决方法是不让他饱对方的锁,将锁(synchronized同步块)拿出来
     1 package com.thread.syn;
     2 
     3 //死锁:多个线程互相抱着对方需要的资源,然后形成僵持
     4 public class DeadLock {
     5     public static void main(String[] args) {
     6         Makeup g1 = new Makeup(0, "灰姑凉");
     7         Makeup g2 = new Makeup(1, "白雪公主");
     8 
     9         g1.start();
    10         g2.start();
    11     }
    12 }
    13 
    14 //口红
    15 class Lipstick {
    16 
    17 }
    18 
    19 //镜子
    20 class Mirror {
    21 
    22 }
    23 
    24 //化妆
    25 class Makeup extends Thread {
    26 
    27     //需要的资源只有一份,用static来保证只有一份
    28     static Lipstick lipstick = new Lipstick();
    29     static Mirror mirror = new Mirror();
    30 
    31     int choice;//选择
    32     String girlName;//使用化妆品的人
    33 
    34     Makeup(int choice, String girlName) {
    35         this.choice = choice;
    36         this.girlName = girlName;
    37     }
    38 
    39 
    40     @Override
    41     public void run() {
    42         //化妆
    43         try {
    44             makeup();
    45         } catch (InterruptedException e) {
    46             e.printStackTrace();
    47         }
    48     }
    49 
    50     //化妆,互相持有对方的锁,就是互相拿到对方的资源
    51     private void makeup() throws InterruptedException {
    52         if (choice == 0) {
    53             synchronized (lipstick) {//获得口红的锁
    54                 System.out.println(this.girlName + "获得口红的锁");
    55                 Thread.sleep(1000);
    56             }
    57             synchronized (mirror) {//1s以后获得镜子的锁
    58                 System.out.println(this.girlName + "获得镜子的锁");
    59             }
    60         } else {
    61             synchronized (mirror) {//获得镜子的锁
    62                 System.out.println(this.girlName + "获得镜子的锁");
    63                 Thread.sleep(2000);
    64             }
    65             synchronized (lipstick) {//2s以后想获得口红的锁
    66                 System.out.println(this.girlName + "获得口红的锁");
    67             }
    68         }
    69 
    70     }
    71 
    72 }
    73 
    74 结果:
    75 灰姑凉获得口红的锁
    76 白雪公主获得镜子的锁
    77 灰姑凉获得镜子的锁
    78 白雪公主获得口红的锁
    死锁避免方法
    • 产生死锁的四个必要条件:
      • 互斥条件:一个资源每次只能被一个进程使用
      • 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
      • 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺
      • 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
    • 上面列出了死锁的四个必要条件,我们只要想办法破其中的任意一个或多个条件就可以避免死锁发生。


  • 相关阅读:
    Mac下PyCharm快捷键大全
    SQL语句优化
    There was a problem confirming the ssl certificate: [SSL: TLSV1_ALERT_PROTOCOL_VERSION] tlsv1 alert protocol version (_ssl.c:661)
    Hadoop Trash回收站使用指南
    HDFS 中向 DataNode 写入数据失败了怎么办
    mapreduce 实现写出orc文件
    mapreduce读取压缩文件
    hive开窗函数over(partition by ......)用法
    Mac 安装 home Brew以及 XCTool的过程记录
    iOS开发中使用CocoaPods来管理第三方的依赖程序
  • 原文地址:https://www.cnblogs.com/duanfu/p/12260776.html
Copyright © 2020-2023  润新知