应该使用可以证明“易失性”声明的代码示例
2022-09-03 09:47:43
目前,我无法理解我们何时应该使用来声明变量。volatile
我做了一些研究,并搜索了一些关于它的材料很长一段时间,并且知道当一个字段被声明为易失性时,编译器和运行时会注意到这个变量是共享的,并且对它的操作不应该与其他内存操作重新排序。
但是,我仍然无法理解我们应该在什么情况下使用它。我的意思是,有人可以提供任何示例代码来证明使用“volatile”会带来好处或解决问题吗?
目前,我无法理解我们何时应该使用来声明变量。volatile
我做了一些研究,并搜索了一些关于它的材料很长一段时间,并且知道当一个字段被声明为易失性时,编译器和运行时会注意到这个变量是共享的,并且对它的操作不应该与其他内存操作重新排序。
但是,我仍然无法理解我们应该在什么情况下使用它。我的意思是,有人可以提供任何示例代码来证明使用“volatile”会带来好处或解决问题吗?
下面是一个示例,说明为什么是必要的。如果删除关键字,线程 1 可能永远不会终止。(当我在Linux上的Java 1.6 Hotspot上进行测试时,情况确实如此 - 你的结果可能会有所不同,因为JVM没有义务对未标记的变量进行任何缓存。volatile
volatile
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();
}
}
以下是易失性必要性的规范示例(在本例中为变量。没有它,热点将提升环路()外部的访问,并且永远不会终止。这将发生在大多数服务器 JVM 上。str
while (str == null)
run()
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!!");
}
}