让我们执行以下代码:
package attempt;
import java.util.concurrent.*;
class Writer implements Runnable {
public void run() {
Main.x = 1;
// Main.secret=true;
}
}
class Reader implements Runnable {
public void run() {
// boolean unused = Main.secret;
System.out.println(Main.x);
}
}
public class Main {
public static int x = 0;
public static volatile boolean secret = false;
public static void main(String[] args){
ExecutorService exec = Executors.newSingleThreadExecutor();
exec.execute(new Writer());
exec.execute(new Reader());
exec.shutdown();
}
}
我们可以肯定地说,对于这个程序,不能保证输出会是一个,因为线程Reader'a 不一定看到Writer线程 'a 执行的操作(请参阅处理器缓存)。
问题:如果您取消注释程序的所有注释,是否可以 100% 保证程序的输出为 1?
换句话说:它会完全像这样吗?
Main.x = 1;
<< // внутри одного потока
Main.secret=true;
<< // между записью и чтением volatile
boolean unused = Main.secret;
<< // внутри одного потока
System.out.println(Main.x);
,其中“<<” - 发生在之前。
如果您计划并行运行线程但 Writer 有点早, volatile 不会给您保证
Main.x == 1。volatile 修饰符仅确保您在读取后在 Reader 中更改 volatile 变量之前看到所有 Writer 更改。不应将其视为一种同步方式,而应将其视为一种方式,例如,正确读取有关在另一个线程中完成某些操作的共享标志。
在您给出的示例中,您可以在循环中选中复选框: