分析死锁形成的原理,与避免死锁的方法。
死锁的形成原理
先用一段代码来模拟死锁:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34
| public class DeadLockDemo { private static String A = "A"; private static String B = "B"; public static void main(String[] args) { Thread t1 = new Thread(new Runnable() { @Override public void run() { synchronized(A) { try { Thread.currentThread().sleep(2000); } catch (interruptedException e) { e.printStackTrace(); } synchronized(B) { System.out.println("t1"); } } } }); Thread t2 = new Thread(new Runnable() { @Override public void run() { synchronized(B) { synchronized(A) { System.out.println("t2"); } } } }); t1.start(); t2.start(); } }
|
上面的代码t1线程锁定资源A,然后睡眠2秒后需要锁定资源B才能结束运行,t2线程直接锁定了资源B,然后需要锁定资源A才能结束运行,由于两个线程都无法拿到需要的资源,所以都处于阻塞状态。
避免死锁的方法
- 避免一个线程同时获取多个锁。
- 避免一个线程在锁内同时占用多个资源,尽量保证每个锁子占用一个资源。
- 使用定时锁lock.tryLock(timeout)来代替内部锁机制。
- 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则会出现解锁失败的情况。