内容来自《java并发编程的艺术》
死锁是啥呢?
上一段代码:
public class DeadLockDemo {
private static String A = "A";
private static String B = "B";
public static void main(String[] args) {
new DeadLockDemo().deadLock();
}
private void deadLock() {
Thread t1 = new Thread(new Runnable() {
@Override public void run() {
//先锁住A这个对象
synchronized (A) { try {
//睡眠2000毫秒
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
//然后去获取B对象的锁,此时B对象的锁已经被线程t2获得,如果t2不释放锁的话t1是获取不到的
}synchronized (B) {
System.out.println("1");
}
}
}
});
Thread t2 = new Thread(new Runnable() {
@Override public void run() {
//先锁住B这个对象
synchronized (B) {
//然后去获取A对象的锁,此时A对象的锁已经被线程t1获得,如果t1不释放锁的话t2也获取不到
synchronized (A) { System.out.println("2");
}
}
}
}); t1.start(); t2.start(); }
}
应该能看明白,看不明白就复制到idea跑一下。
死锁通俗来说就是线程资源冲突,比如在并发的情况下A线程获得了资源1它接下来需要资源2,同时B线程获得了资源2接下来需要资源1,这时线程A没有获得所需资源不会释放,同样,线程B也是如此,两个线程就会阻塞,如果不设置锁超时过期就会出现一直死锁的情况,在真实开发环境这种情况是很致命的(当然一般测试环境这种代码就被kill了)。
下面说几个在书里看到的避免死锁的常见方法:
1.避免一个线程获得多个锁
2.避免一个线程在锁内同时占用多个资源,尽量一个锁至占用一个资源
3.尝试使用定时锁,使用lock.tryLock(timeout)来代替内部锁
4.对于数据库锁,加锁解锁必须在一个数据库连接里,不然会出现解锁失败的情况。