最近在继续了解synchronize的过程中,回想起项目曾经发生过由于synchronized被滥用,而导致死锁的问题。所以简单用一篇文章记录下,模拟业务代码,分析下原因以提醒自己。
大概的操作如下:
当两个资源都需要进行操作的时候,由于都锁对象,而且保持请求,所以直接就死锁了。
public class synTest {
public static void main(String[] args) {
//玩家财富资源
Object playerWealth = new Object();
//玩家背包
Object playerBackPack = new Object();
new Thread(() -> {
synchronized (playerWealth) {
System.out.println(Thread.currentThread().getName() + "正在操玩家财富");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (playerBackPack) {
System.out.println(Thread.currentThread().getName() + "正在操玩家背包");
}
}
}, "One").start();
new Thread(() -> {
synchronized (playerBackPack) {
System.out.println(Thread.currentThread().getName() + "正在操玩家背包");
try {
Thread.sleep(200);
} catch (InterruptedException e) {
e.printStackTrace();
}
synchronized (playerWealth) {
System.out.println(Thread.currentThread().getName() + "正在操玩家财富");
}
}
}, "Two").start();
}
}
虽然说这种问题一般遇到的机会也并不多,但是也不容忽视。这个情况对于理解死锁产生的四个条件(占有且等待、互斥、不可抢夺、循环等待),也是有一定帮助的。