多线程环境中的布尔值

时间:2017-07-10 08:59:34

标签: java multithreading concurrency

我有布尔字段:

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?

3 个答案:

答案 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。这就够了。