多线程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 白雪公主获得口红的锁
死锁避免方法
  • 产生死锁的四个必要条件:
    • 互斥条件:一个资源每次只能被一个进程使用
    • 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
    • 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺
    • 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
  • 上面列出了死锁的四个必要条件,我们只要想办法破其中的任意一个或多个条件就可以避免死锁发生。


原文地址:https://www.cnblogs.com/duanfu/p/12260776.html