多线程的死锁
Java 线程死锁是一个经典的多线程问题,因为不同的线程都在等待根本不可能被释放的锁,从而导致所以的任务都无法继续完成。在多线程技术中,“死锁” 是必须避免的,因为这会造成线程的 “假死”。
public class DealThread implements Runnable {
public String username;
public Object lock1 = new Object();
public Object lock2 = new Object();
public void setFlag(String username) {
this.username = username;
}
@Override
public void run() {
if (username.equals("a")) {
synchronized (lock1) {
try {
System.out.println("username=" + username);
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrack();
}
}
synchronized(lock2) {
System.out.println("按 lock1 -> lock2 代码顺序执行了");
}
}
if (username.equals("b")) {
synchronized (lock2) {
try {
System.out.println("username=" + username);
Thread.sleep(3000);
} catch (InterruptedException e) {
e.printStackTrack();
}
}
synchronized(lock1) {
System.out.println("按 lock2 -> lock1 代码顺序执行了");
}
}
}
}
public static void main (String[] args) {
try {
DealThread t1 = new DealThread();
t1.setFlag("a");
Thread thread1 = new Thread(t1);
thread1.start();
Thread.sleep(100);
t1.setFlag("b");
Thread thread2 = new Thread(t1);
thread2.start();
} catch (InterruptedException e) {
e.printStackTrack();
}
}
程序运行结果:
username = a
username = b
监测是否死锁
可以使用 JDK 自带的工具来监测是否有死锁的现象。首先进入 CMD 工具,执行 jps 命令。
jps
1852 Jps
3352
3244 Run
得到运行的线程 Run 的 id 值是 324。再执行 jstack 命令,查看结果。
jstack -l 3244
...
...
found 1 deadlock
出现 found 1 deadlock,即发现一个死锁
锁对象的改变
在将任何数据类型作为同步锁时,需要注意的是,是否有多个线程同时持有锁对象,如果同时持有相同的锁对象,则这些线程之间就是同步的;如果分别获的锁对象,这些线程之间就是异步的。
更新于2019年05月05日