多线程17:死锁
作者:互联网
死锁:
- 多个线程各自占有一些共享资源,并且互相等待其他线程占有的资源才能运行,而导致两个或者多个线程都在等待对方释放资源,都停止执行的情形。某一个同步块同时拥有"两个以上对象的锁"时,就可能会发生"死锁"的问题。
- 首先要有两个对象口红 Lipstick 类 和镜子 Mirror 类
- 然后需要一件事情,比如都要去化妆 Makeup 类继承一下Thread类重写run方法,只有一份资源(用static保证只有一份),一个口红一个镜子。
- 我呢,先拿到了口红,你呢,你先拿了镜子。
- 1秒钟以后我想拿镜子,2秒后你想拿口红,于是你们两互相僵持,不想给对方。
- 于是启动线程后,发现程序卡死了。
- 然后解决方法是不让他饱对方的锁,将锁(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 白雪公主获得口红的锁死锁避免方法
- 产生死锁的四个必要条件:
- 互斥条件:一个资源每次只能被一个进程使用
- 请求与保持条件:一个进程因请求资源而阻塞时,对已获得的资源保持不放。
- 不剥夺条件:进程已获得的资源,在未使用完之前,不能强行剥夺
- 循环等待条件:若干进程之间形成一种头尾相接的循环等待资源关系。
- 上面列出了死锁的四个必要条件,我们只要想办法破其中的任意一个或多个条件就可以避免死锁发生。
标签:girlName,17,镜子,口红,Makeup,获得,死锁,多线程 来源: https://www.cnblogs.com/duanfu/p/12260776.html