并发挑战(二)
程序员文章站
2022-03-26 22:49:34
死锁锁是一个很有用的工具,运用的场景也多,使用也简单,但是,锁使用不当也会出现一系列维妮塔,比如说:死锁,一旦产生死锁,会造成系统功能无法使用。例如:public class DeadLockDemo { private static String A = "A"; private static String B = "B"; private void deadLock(){ Thread t1 = new Thread(()->{...
死锁
锁是一个很有用的工具,运用的场景也多,使用也简单,但是,锁使用不当也会出现一系列维妮塔,比如说:死锁,一旦产生死锁,会造成系统功能无法使用。
例如:
public class DeadLockDemo {
private static String A = "A";
private static String B = "B";
private void deadLock(){
Thread t1 = new Thread(()->{
synchronized (A) {
try {
Thread.currentThread().sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (B) {
System.out.println("1");
}
}
});
Thread t2 = new Thread(()->{
synchronized (B){
synchronized (A){
System.out.println("2");
}
}
});
t1.start();
t2.start();
}
public static void main(String[] args) {
new DeadLockDemo().deadLock();
}
}
在这段代码中,t1和t2互相等待对方释放锁资源,造成了程序死锁
上述这段代码只是演示了,死锁的场景,在现实生活中,不会这样去写代码,但是在一些复杂的场景中,可能会遇到这样的问题,如:t1拿到锁之后,由于一些原因或者异常没有释放锁(死循环)抑或t1拿到的是数据库锁,释放锁的时候,抛出异常,没有释放掉。
一旦出现死锁,业务层是可以感知到的。
避免死锁的几个常见方法
- 避免一个线程同时获取多个锁
- 避免一个线程在锁内同时占用多个资源,尽量保证每个锁只占用一个资源
- 尝试使用定时锁,使用lock.tryLock(timeout)来替代使用内部锁机制
- 对于数据库锁,加锁和解锁必须在一个数据库连接里,否则可能会出现解锁失败的情况
本文地址:https://blog.csdn.net/weixin_48013460/article/details/112236331