我有布尔字段:
private boolean isReady = false;
private boolean isReady() {
return isReady;
}
我在两种方法中使用它:
synchronized (topologyLock)
{
try
{
while(!instance.isReady())
{
topologyLock.wait();
}
}
catch (InterruptedException e)
{
Thread.currentThread().interrupt();
}
private synchronized boolean topologyChanged()
{
synchronized(topologyLock)
{
isReady = true;
topologyLock.notifyAll();
}
}
我认为上面的代码应该可以正常工作 - 或者我是否需要将这个布尔变量设置为volatile?
答案 0 :(得分:3)
引自stone ages:
那么,何时使变量变为volatile?
当你有一个可以被许多线程访问的变量,并且你希望每个线程获得该变量的最新更新值,即使该值由程序中的任何其他线程/进程/更新。
所以人们可以认为volatile
在这里是必要的。但是(正如Kayaman正确指出的那样):它完全是关于Java内存模型的。事实synchronized
不仅可以阻止竞争条件(因为只有一个线程可以在任何时间点更新数据),而且还会建立 happens before 关系。
因此:上述代码没有竞争条件;并且它还确保每个线程都能看到"正确的"价值isReady
。
当然,如果您碰巧在同步区块中操纵isReady
,那么所有投注都会被取消。
答案 1 :(得分:0)
不,因为你只是在synchronized
块中与它进行交互,根据定义,它只在一个线程上运行。
答案 2 :(得分:0)
如果您导出的代码是访问isReady
的唯一代码,那么它是正确的。
相反,如果这是编写isReady
的代码的唯一部分,则需要将isReady
定义为volatile
,以便从代码的其他部分正确读取它。
在任何情况下,如果相关的同步代码是您发布的代码,则将topologyChanged
方法定义为synchronized
是不正确的,因为您在内部使用监视器topologyLock
。这就够了。