在多线程问题中,死锁是一个常见的问题,原因是不同的线程都在等待根本不可能被释放的锁,从而导致所有的任务都无法继续完成。
先看下面的例子:
package com.example.test;
public class Test188 {
public static void main(String[] args) {
MyThreadTask22 mtt = new MyThreadTask22();
mtt.setName("a");
Thread t = new Thread(mtt);
t.start();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
mtt.setName("b");
Thread t1 = new Thread(mtt);
t1.start();
}
}
class MyThreadTask22 implements Runnable{
private String name;
private Object o1 = new Object();
private Object o2 = new Object();
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public void run() {
// TODO Auto-generated method stub
if(name.equals("a")) {
synchronized (o1) {
System.out.println(name);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (o2) {
System.out.println("执行结束");
}
}
}
if(name.equals("b")) {
synchronized (o2) {
System.out.println(name);
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
synchronized (o1) {
System.out.println("执行结束");
}
}
}
}
}
可以看出第一个线程在获取锁1之后,执行耗时操作,而这是第二个线程获取锁2,执行耗时操作,第一个线程耗时操作结束,获取不到锁2,无法继续执行,第二个线程耗时操作结束,获取不到锁1,无法继续执行,至此,两个线程都无法完成。
我们可以借助JDK自带的工具来检测死锁线程。打开cmd,进入到JDK安装文件的bin目录,执行jps命令,你必须保证你的程序要在运行。
得到运行的线程的id为5404,在执行jstack命令。
可以看到报出的异常: