java无竞争条件:两个具有不同锁但共享数据相同的块
我有两个线程对同一个对象调用不同的方法
- 线程1调用
unsafeObj.incrementVAR_v1()
10次 - 线程2调用
unsafeObj.incrementVAR_v2()
10次
这两个实例方法都有一个synchronized
块,该块具有不同的锁(LOCK_1和LOCK_2)访问同一实例字段VAR
public void icrementVAR_v1() {
synchronized(LOCK_1) {
++VAR;
print("Thread 1: " + VAR)
}
}
public void incrementVAR_v2() {
synchronized(LOCK_2) {
++VAR;
print("Thread 2: " + VAR);
}
}
👉 考虑到这两个synchronized
块使用不同的锁,我本以为VAR
会被并发访问,从而导致更新丢失(VAR
小于20)。然而,这不是我所观察到的。有人能给我解释一下为什么不是这样吗
示例输出:
Thread 2: 2
Thread 1: 1
Thread 2: 3
Thread 1: 4
Thread 2: 5
Thread 1: 6
Thread 2: 7
Thread 1: 8
Thread 2: 9
Thread 1: 10
Thread 2: 11
Thread 1: 12
Thread 2: 13
Thread 1: 14
Thread 2: 15
Thread 1: 16
Thread 2: 17
Thread 1: 18
Thread 2: 19
Thread 1: 20
# 1 楼答案
正如我所料,对
VAR
字段的并发访问(由于有两个不同的锁)确实会导致竞争条件,但为了观察它,需要大量的迭代(在我的情况下,每个线程中有10万次迭代)。经验教训:# 2 楼答案
只是为了好玩,在10分钟内完成(当然,这不是保证)
输出示例: