zoukankan      html  css  js  c++  java
  • 36 多线程(八)——线程造成死锁

    一线程持有a资源,需要获取b资源才释放a资源。

    二线程持有b资源,需要获取a资源才释放b资源。

    造成死锁。

    下面举个例子:

    两个女人化妆,需要镜子和口红,两个人一个先拿镜子,再拿口红,另一个先拿口红,再拿镜子
    /**
     * @author TEDU
     * 死锁出现的情况多是锁套锁。
     */
    public class DeadLock {
    	public static void main(String[] args) {
    		MakeUp m1 = new MakeUp("小红",1);
    		MakeUp m2 = new MakeUp("小丽",2);
    		m1.start();
    		m2.start();
    	}
    }
    
    //镜子
    class Mirror{
    	
    }
    
    //口红
    class Lipstick{
    	
    }
    
    //化妆
    
    class MakeUp extends Thread{
    	//这里是静态修饰,保证她们拿到的是同一个镜子和口红
    	private static Mirror mirror = new Mirror();
    	private static Lipstick lipstick = new Lipstick();
    	private String name;
    	private int choice;
    	
    	public MakeUp(String name,int choice) {
    		this.name = name;
    		this.choice = choice;
    	}
    	@Override
    	public void run() {
    		// TODO Auto-generated method stub
    		super.run();
    		makeUp(choice);
    	}
    	
    	public void makeUp(int choice) {
    		if(choice == 1) {
    			synchronized (mirror){
    				//先拿了镜子
    				System.out.println(name+"拿了镜子");
    				
    				try {
    					Thread.sleep(2000);
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    				synchronized (lipstick) {//写在锁中的锁:拿口红
    					//再拿了镜子
    					System.out.println(name+"拿了口红");
    				}
    			}
    		}else {
    			synchronized (lipstick){
    				//先拿了口红
    				System.out.println(name+"拿了口红");
    				try {
    					Thread.sleep(1000);
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    				synchronized (mirror) {//写在锁中的锁:拿镜子
    					//再拿了镜子
    					System.out.println(name+"拿了镜子");
    				}
    			}
    		}
    	}
    }
    

      

    这个程序就会造成死锁。

    本例解决方法:放下已有资源(解锁),再获取另一个资源。

    也就是将锁套锁解除,将写在同步块里的同步块拿出来并列即可。

    if(choice == 1) {
    			synchronized (mirror){
    				//先拿了镜子
    				System.out.println(name+"拿了镜子");
    				
    				try {
    					Thread.sleep(2000);
    				} catch (InterruptedException e) {
    					// TODO Auto-generated catch block
    					e.printStackTrace();
    				}
    			}
    			synchronized (lipstick) {//锁单独写出来:拿口红
    				//再拿了镜子
    				System.out.println(name+"拿了口红");
    			}
    		}
    

      

  • 相关阅读:
    Java 零基础跑起第一个程序
    Xcode6 引入第三方静态库project的方法
    Cocos2d-x3.0 RenderTexture(三)
    POJ 题目3461 Oulipo(KMP)
    unity3D游戏开发实战原创视频讲座系列9之塔防类游戏开发第一季
    android 虚拟按键是通过哪种机制上报的?
    深入理解 C 指针阅读笔记 -- 第五章
    【1】按照Django官网,编写一个web app 创建project/配置数据库
    [Swift]LeetCode442. 数组中重复的数据 | Find All Duplicates in an Array
    [Swift]LeetCode441. 排列硬币 | Arranging Coins
  • 原文地址:https://www.cnblogs.com/Scorpicat/p/11994748.html
Copyright © 2011-2022 走看看