简体   繁体   English

多线程环境中的布尔值

[英]Boolean in Multithreaded environment

I have boolean field: 我有布尔字段:

private boolean isReady = false;
private boolean isReady() {
  return isReady;
}

and I am using it inside two methods: 我在两种方法中使用它:

synchronized (topologyLock)
{
   try 
    {
      while(!instance.isReady()) 
      {
        topologyLock.wait();
      }
    } 
    catch (InterruptedException e)
    {               
        Thread.currentThread().interrupt();
    } 

private synchronized boolean topologyChanged()
{           
    synchronized(topologyLock)
    {
        isReady = true;
        topologyLock.notifyAll();
    }
}

I think that above code should work perfectly - or do I need to make this boolean variable volatile? 我认为上述代码应该可以完美工作-还是需要使此布尔变量具有可变性?

Quoting from stone ages : 引用石器时代

So, when to make a variable volatile? 那么,何时使变量可变?

When you have a variable which can be accessed by many threads and you want every thread to get the latest updated value of that variable even if the value is updated by any other thread/process/outside of the program. 当您拥有一个可以被许多线程访问的变量,并且您希望每个线程都获得该变量的最新更新值时,即使该值是由程序的任何其他线程/进程/外部更新的。

So one could think that volatile is necessary here. 因此,人们可能会认为在这里volatile是必要的。 But (as Kayaman pointed out correctly): it is all about the Java memory model. 但是(正如Kayaman正确指出的那样):这全都与Java内存模型有关。 And the fact that synchronized not only prevents race conditions (as only one thread can update data at any point in time) but also establishes a happens before relation. 而且, synchronized不仅可以防止争用情况 (因为只有一个线程可以在任何时间更新数据),而且可以关联之前发生

Therefore: the above code doesn't have race conditions; 因此:上面的代码没有竞争条件; and it also makes sure that each thread sees the "correct" value of isReady . 并且还确保每个线程都能看到isReady的“正确”值。

Of course, if you ever happen to manipulate isReady out of a synchronized block, then all bets are off. 当然,如果您碰巧从同步块中操作isReady ,那么所有选择都将关闭。

不,因为您仅在synchronized块中与之交互,按照定义, synchronized块仅在一个线程上运行。

If the code that you exported is the only code accessing isReady , it is correct. 如果您导出的代码是唯一访问isReady代码,则它是正确的。

Instead if this is the only part of code writing isReady , you need to define isReady as volatile to read it correctly from another part of code. 相反,如果这是编写isReady的代码的唯一部分,则需要将isReady定义为volatile才能从另一部分代码正确读取它。

In any case if the relevant synchronized code is the code that you posted, is incorrect defining the method topologyChanged as synchronized because internally you are using the monitor topologyLock . 在任何情况下,如果相关的同步代码是您发布的代码,则将方法topologyChanged更改定义为已synchronized是错误的,因为在内部使用的是监视器topologyLock It is enough. 够了

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM