应该使用可以证明“volatile”声明的代码示例
目前我无法理解什么时候应该使用volatile
来声明变量。
我已经做了一些研究并且搜索了很长时间的一些资料,并且知道当一个字段被声明为volatile时,编译器和运行时会注意到这个变量是共享的,并且它的操作不应该与其他内存重新排序操作。
但是,我仍然无法理解我们应该在什么情况下使用它。 我的意思是可以有人提供任何示例代码,可以证明使用“易失性”带来好处或解决问题相比,而不使用它?
这是volatile
为什么是必需的一个例子。 如果删除关键字volatile
,则线程1可能永远不会终止。 (当我在Linux上的Java 1.6 Hotspot上进行测试时,情况确实如此 - 您的结果可能会有所不同,因为JVM没有义务对未标记为volatile
的变量进行任何缓存。)
public class ThreadTest {
volatile boolean running = true;
public void test() {
new Thread(new Runnable() {
public void run() {
int counter = 0;
while (running) {
counter++;
}
System.out.println("Thread 1 finished. Counted up to " + counter);
}
}).start();
new Thread(new Runnable() {
public void run() {
// Sleep for a bit so that thread 1 has a chance to start
try {
Thread.sleep(100);
} catch (InterruptedException ignored) {
// catch block
}
System.out.println("Thread 2 finishing");
running = false;
}
}).start();
}
public static void main(String[] args) {
new ThreadTest().test();
}
}
下面是一个挥发性(在这种情况下是str
变量的一个典型例子),如果没有它,热点会提升循环外的访问( while (str == null)
)和run()
永远不会终止。大多数服务器JVM。
public class DelayWrite implements Runnable {
private String str;
void setStr(String str) {this.str = str;}
public void run() {
while (str == null);
System.out.println(str);
}
public static void main(String[] args) {
DelayWrite delay = new DelayWrite();
new Thread(delay).start();
Thread.sleep(1000);
delay.setStr("Hello world!!");
}
}
埃里克,我已阅读你的意见,特别是一个罢工
事实上,我可以理解概念层面上volatile的用法。 但是对于实践而言,我无法想象没有使用volatile的并发问题的代码
你可能遇到的显而易见的问题是编译器重新排序,例如Simon Nickerson提到的更为着名的提升。 但让我们假设不会有重新排序,那个评论可能是一个有效的评论。
另一个问题,即易失性解析与64位变量(长,双)。 如果您写入长整数或双整数,则将其视为两个独立的32位存储。 并发写入会发生什么情况是一个线程的高32被写入寄存器的高32位,而另一个线程写低32位。 那么你可以有一个很长的,既不是一个,也不是另一个。
另外,如果你看看JLS的内存部分,你会发现它是一个放松的内存模型。
这意味着一段时间写入操作可能无法看到(可能会驻留在存储缓冲区中)。 这可能导致陈旧的读取。 现在你可能会说这看起来不太可能,但是你的程序是不正确的,有可能失败。
如果你在应用程序的生命周期中增加了一个int,并且你知道(或者至少以为)int不会溢出,那么你不会将其升级到很长的时间,但它仍然是可能的。 在内存可见性问题的情况下,如果您认为它不应该对您产生影响,您应该知道它仍然可以并且可能会导致难以识别的并发应用程序中的错误。 正确性是使用volatile的原因。
链接地址: http://www.djcxy.com/p/91965.html上一篇: The code example which can prove "volatile" declare should be used