死锁是Java多线程的重要概念之一,也经常出现在各大公司的笔试面试之中。那么如何创造出一个简单的死锁情况?请看代码:

class Test implements Runnable    
{
    boolean flag;  
    Test(boolean flag)
    {
        this.flag = flag;
    }
    public void run()    
    {
        if(flag)
        {
            while(true)    //这里用while(true)使得线程在这里无限循环,可以避免各种随机情况造成死锁不成功
            synchronized(MyLock.a)    //这里设置同步锁为MyLock.a
            {
                System.out.println("Afirstlayer");
                synchronized(MyLock.b)    //这里设置同步锁为MyLock.b
                {
                    System.out.println("Asecondlayer");
                }
            }
        }
        else
        {
            while(true)
            synchronized(MyLock.b)    //这里设置同步锁为MyLock.b
            {
                System.out.println("Bfirstlayer");
                synchronized(MyLock.a)    //这里设置同步锁为MyLock.a
                {
                    System.out.println("Bsecondlayer");
                }
            }
            
        }
    }
}

class MyLock    //创建两个同步锁对象
{
    public static final Object a = new Object();
    public static final Object b = new Object();
}

class DeadLock
{
    public static void main(String[] args)
    {
        Test x = new Test(true);    
        Test y = new Test(false);    //这里分别新建两个flag分别为true和false的Test实例,这样它们所对应的线程会进入run()中不同的分支
        Thread t1 = new Thread(x);
        Thread t2 = new Thread(y);
        t1.start();
        t2.start();
    }
}

很显然,当t1和t2启动后执行run(),进入第一层后它们分别会占用MyLock.a和MyLock.b这两个同步锁。

然而如果想进入第二层同步块它们又分别需要MyLock.b和MyLock.a,这就导致了它们都无法进行下去,造成死锁情况。

运行结果如下:

java线程死亡 java线程死锁代码_同步锁

运行之后程序卡住,只能按Ctrl+C才能回到命令行输入状态。