死锁就是多个线程发生了互相等待的情况。
如下代码,t1获取了lock1,并希望获取lock2.
t2已经获取了lock2,并希望获取lock1.
在这种情况下,两边都在等待获取锁,这就导致了两边都不会结束,也不会释放锁。
public class DeadLock {
public static void main(String[] args) {
Object lock1 = new Object();
Object lock2 = new Object();
Thread t1 = new Thread(new Runnable() {
@Override
public void run() {
synchronized (lock1) {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
synchronized (lock2) {
}
}
}
}, "deadLock - 1");
t1.start();
ExecutorService executorService = Executors.newFixedThreadPool(200);
for (int i = 0; i < 200; i++) {
executorService.submit(new Runnable() {
@Override
public void run() {
synchronized (lock2) {
try {
Thread.sleep(1000);
} catch (Exception e) {
}
synchronized (lock1) {
}
}
}
});
}
}
}
当然在实际中,我们是不会写出这种代码的。
但是有可能产生不同服务之间的死锁,两个服务互相等待的情况。
那么避免死锁产生的几个常用方法:
- 避免一个线程同时获取多个锁。
- 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源。
- 尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制。
- 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况。
以上摘自《Java并发编程的艺术》。