java 多线程()—— 死锁

Posted 玛丽莲茼蒿

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java 多线程()—— 死锁相关的知识,希望对你有一定的参考价值。

在学习操作系统时,已经反复理解很多遍了,所以我们直接给出死锁的例子:

一个经典的小品《不差钱》

 

public class DeadLock 
    public static void main(String[] args) 
        ServerDinner serverDinner = new ServerDinner(); //上菜的权利只有一份,这很重要!
        CanSing canSing = new CanSing(); //唱歌的权利只有一份,这很重要!
        //赵本山:拥有让小沈阳唱歌的权利,还想要上菜
        ZhaoBenShan zhaoBenShan = new ZhaoBenShan(serverDinner,canSing);  
        zhaoBenShan.start();
        //小沈阳:拿着上菜的权利,还想要唱歌的权利
        XiaoShenYang xiaoShenYang = new XiaoShenYang(serverDinner,canSing);
        xiaoShenYang.start();
    


//上菜的权利
class ServerDinner 

//唱歌的权利
class CanSing

//小沈阳:拿着上菜的权利,还想要唱歌的权利
class XiaoShenYang extends Thread
    ServerDinner serverDinner;
    CanSing canSing;

    public XiaoShenYang(ServerDinner serverDinner,CanSing canSing)
        this.serverDinner = serverDinner;
        this.canSing = canSing;
    

    @Override
    public void run() 
        synchronized (serverDinner)
            System.out.println("小沈阳:你不让我唱歌我就不给你上菜");
            try 
                Thread.sleep(1000);
             catch (InterruptedException e) 
                e.printStackTrace();
            

            synchronized (canSing)
                System.out.println("小沈阳:成功唱歌");
            
        
    


//赵本山:拥有让小沈阳唱歌的权利,还想要上菜
class ZhaoBenShan extends Thread
    ServerDinner serverDinner;
    CanSing canSing;

    public ZhaoBenShan(ServerDinner serverDinner,CanSing canSing)
        this.serverDinner = serverDinner;
        this.canSing = canSing;
    

    @Override
    public void run() 
        synchronized (canSing)
            System.out.println("赵本山:先上菜再唱歌");
            try 
                Thread.sleep(1000);
             catch (InterruptedException e) 
                e.printStackTrace();
            

            synchronized (serverDinner)
                System.out.println("赵本山:成功得到菜");
            
        
    

运行结果: 

注意,唱歌的权利和上菜的权利只能有一份。如果唱歌或者上菜的权利有两份,那么就不会产生死锁了。

如何解决死锁?

对于小沈阳,把 synchronized (canSing) 的代码段拿出来从 synchronized (serverDinner)中拿出来 。也就意味着让出上菜的权利之后,再去索要唱歌的权利。

 对于赵本山,同样的道理。先让出唱歌的权利,再索要上菜的权利。

 

以上是关于java 多线程()—— 死锁的主要内容,如果未能解决你的问题,请参考以下文章

Java多线程死锁问题

Java自学-多线程 死锁

java多线程死锁及死锁问题排查

Java线程和多线程——死锁

如何解决多线程造成的数据库死锁

用java多线程编写哲学家就餐程序 利用多线程技术编写哲学家就餐程序,使之在运行时能演示产生死锁的情况,