死锁就是多个线程发生了互相等待的情况。
如下代码,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() {@Overridepublic 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() {@Overridepublic void run() {synchronized (lock2) {try {Thread.sleep(1000);} catch (Exception e) {}synchronized (lock1) {}}}});}}}
当然在实际中,我们是不会写出这种代码的。
但是有可能产生不同服务之间的死锁,两个服务互相等待的情况。
那么避免死锁产生的几个常用方法:
- 避免一个线程同时获取多个锁。
- 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源。
- 尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制。
- 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况。
以上摘自《Java并发编程的艺术》。
