代码片段 - 1
class RequestObject implements Runnable
{
private static Integer nRequests = 0;
@Override
public void run()
{
synchronized (nRequests)
{
nRequests++;
}
}
}
代码片段 - 2
public class Racer implements Runnable
{
public static Boolean won = false;
@Override
public void run()
{
synchronized (won)
{
if (!won)
won = true;
}
}
}
我遇到了第一个代码片段的竞争条件。我知道这是因为我获得了一个不可变对象(整数类型)的锁定。
我编写了第二个代码片段,它再次不受“布尔”不可变的影响。但这有效(输出运行中不显示竞争条件)。如果我正确理解了上一个问题的解决方案,那么以下是可能出错的一种可能方式
- 线程 1 获得了指向的对象(比如 A)的锁
won
- 线程 2 现在尝试获取指向的对象的锁,
won
并进入 A 的等待队列 - 线程 1 进入同步块,验证 A 是否为假,并通过说
won = true
(A 认为它赢得了比赛)来创建一个新对象(比如 B)。 - 'won' 现在指向 B。线程 1 释放对象 A 上的锁(不再由 指向
won
) - 现在,在对象 A 的等待队列中的线程 2 被唤醒并在对象 A 上获得锁,该对象 A 仍然
false
(不变)。它现在进入同步块并假设它也赢了,这是不正确的。
为什么第二个代码片段一直工作正常?