Java 并发问题使volitile无法工作
B线程读取两个全局变量,A线程写入两个全局变量 第二个<代码>怎么可能比第一个<代码>大得多Java 并发问题使volitile无法工作,java,java.util.concurrent,Java,Java.util.concurrent,B线程读取两个全局变量,A线程写入两个全局变量 第二个怎么可能比第一个大得多 public class ThreadTest { private static volatile int first = 0; private static volatile int second = 0; private static class ReaderThread extends Thread { @Override public void run(
public class ThreadTest {
private static volatile int first = 0;
private static volatile int second = 0;
private static class ReaderThread extends Thread {
@Override
public void run() {
while (first < 10000) {
if (first != second) {
System.out.println("ThreadB------first = " + first + ", second = " + second);
}
}
System.out.println("ThreadB------first = " + first + ", second = " + second);
}
}
public static void main(String[] args) throws InterruptedException {
new ReaderThread().start();
Thread.sleep(1000L);
while (first < 10000){
first++;
second++;
}
}
}
那么发生了什么,以及如何解决这个问题呢?在满足“if”之后,执行一些运行速度相对较慢的字符串连接。在从左到右计算println调用的参数表达式时,读取“first”和读取“second”之间可能会经过一些未知的时间长度(可能数百个机器周期) 尝试重新编码为
int f = first, s = second;
if (f != s) {
System.out.println("ThreadB------first = " + f + ", second = " + s);
}
然后看看它是什么样子
更大的问题是,如果这是一些真实代码的片段,那么它似乎无法提供任何有用的同步。每个整数都有立即可见的效果,但两个值之间没有同步。我能看到的唯一保证是,正如所写的,你永远看不到一个小于“第一”值的“第二”值。但是你如何解释将
if(first!=second)
更改为if(first
仍然有效first>second
似乎不可能,因为second在first之后递增,而if
语句在第一个语句之后读取第二个。所以我希望first
和first!=第二个
是等效的。事实上,我想在jvm中用第一个
和第二个
重复指令重排,但失败了。对不起,这句话根本没有意义。我尝试了用户14544949
的答案,结果成功了。请具体说明。是什么让你相信:你永远看不到“秒”的值小于“第一”的值?你是什么意思?你知道,volatile
增量不是原子的,对吗?
int f = first, s = second;
if (f != s) {
System.out.println("ThreadB------first = " + f + ", second = " + s);
}