简体   繁体   English

Java 中的 volatile 关键字

[英]volatile keyword in Java

I am reading "Thinking in Java 4th Edition" right now and I have a question about one paragraph.我现在正在阅读“Thinking in Java 4th Edition”,我对一段有疑问。 (Page 832, in the Concurrency section) (第 832 页,在并发部分)

volatile doesn't work when the value of a field depends on its previous value (such as incrementing a counter), nor does it work on fields whose values are constrained by the values of other fields, such as the lower and upper bound of a Range class which must obey the constraint lower <= upper.当字段的值取决于其先前的值(例如递增计数器)时, volatile 不起作用,也不适用于值受其他字段值约束的字段,例如 a 的下限和上限必须遵守约束下限 <= 上限的范围类。

I don't understand what is "volatile doesn't work" and why keyword volatile has to consider other fields.我不明白什么是“volatile 不起作用”以及为什么关键字volatile必须考虑其他字段。 Can you enlighten me or can you give me some example about it?你能启发我,或者你能给我一些关于它的例子吗? Thank you very much!非常感谢!

volatile doesn't work when the value of a field depends on its previous value当字段的值取决于其先前的值时, volatile 不起作用

volatile int i;

public void bar() {
  if (i == 0) 
    i = 1;
  else 
    i = 2;
}

Considering the above example, if there are two threads which run boo() and check that i is 0, both threads then set i to 1. However, i is expected to be incremented to 2. Volatile cannot guarantee atomicity here.考虑上面的例子,如果有两个线程运行 boo() 并检查 i 是否为 0,那么两个线程都将 i 设置为 1。但是,i 预计会增加到 2。这里 Volatile 不能保证原子性。


nor does it work on fields whose values are constrained by the values of other fields, such as the lower and upper bound of a Range class which must obey the constraint lower <= upper它也不适用于值受其他字段值约束的字段,例如必须遵守约束 lower <= upper 的 Range 类的下限和上限

public class Range {
    private int lower, upper;

    public void setLower(int value) { 
        if (value <= upper) 
          lower = value;
    }

    public void setUpper(int value) { 
        if (value >= lower)                
          upper = value;
    }
}

In this case, making the lower and upper fields volatile cannot guarantee thread-safe.在这种情况下,将lower和upper字段设置为volatile并不能保证线程安全。 For example, assume the initial values of lower and upper are 1 and 10 respectively.例如,假设lower和upper的初始值分别是1和10。 If there are two threads which run setLower(6) and setUpper(4) at the same time, both of them can pass the condition checks which results in an invalid range 6 to 4. So synchronization is needed here to guarantee thread-safe.如果有两个线程同时运行 setLower(6) 和 setUpper(4),它们都可以通过条件检查,导致无效范围 6 到 4。所以这里需要同步以保证线程安全。

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

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