死锁是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,这就导致了它们都无法进行下去,造成死锁情况。
运行结果如下:
运行之后程序卡住,只能按Ctrl+C才能回到命令行输入状态。