下面的代码给出了如下结果:
Change listener
Change listener
Change listener
Incrementing MY_INT to:1
Incrementing MY_INT to:2
Got Change for MY_INT :1loc:0
Change listener
Change listener
Change listener
Change listener
Change listener
Change listener
Change listener
Change listener
Change listener
Incrementing MY_INT to:3
Change listener
Incrementing MY_INT to:4
Incrementing MY_INT to:5
Got Change for MY_INT :3loc:2
Change listener
我的问题是,因为我使用了volatile,所以MY_INT值应该反映为4或5.为什么它不反映。 Soemtimes,即使是那个价值我们得到1.请有人让我知道我哪里出错了。
public class VolatileTest {
private static volatile int MY_INT = 0;
public static void main(String[] args) {
new ChangeListener().start();
new ChangeMaker().start();
}
static class ChangeListener extends Thread {
@Override
public void run() {
int local_value = MY_INT;
while ( local_value < 5){
if( local_value!= MY_INT){
System.out.println("Got Change for MY_INT :"+ MY_INT+"loc:"+local_value);
local_value= MY_INT;
}
System.out.println("Change listener");
}
}
}
static class ChangeMaker extends Thread{
@Override
public void run() {
int local_value = MY_INT;
while (MY_INT <5){
System.out.println("Incrementing MY_INT to:"+(local_value+1));
MY_INT = ++local_value;
}
}
}
}
答案 0 :(得分:0)
这是可能发生的一件事:
ChangeMaker ChangeListener
... ...
MY_INT = 3
Sees MY_INT != 2, calls println(...)
MY_INT = 4
MY_INT = 5
local_value = MY_INT; // 5
all done (MY_INT==5) all done (MY_INT==5)
更改侦听器可能会错过查看更改,因为测试local_value!=MY_INT
不是原子的,具有作业local_value=MY_INT;
答案 1 :(得分:0)
除了一件事,你做得很好,你在访问volatile变量时没有添加同步。与原子不同,volatile变量可以保证您获得实际值而不会更改。我想在你的案例中使用原子作为AtomicInteger
会更好。此外,您可以将int
更改为Integer
将额外synchronized
添加到您的代码中,如下例所示。
public class VolatileTest {
private static volatile Integer MY_INT = 0;
public static void main(String[] args) {
new ChangeListener().start();
new ChangeMaker().start();
}
static class ChangeListener extends Thread {
@Override
public void run() {
int local_value = MY_INT;
while (local_value < 5) {
// ! Here
synchronized (MY_INT) {
if (local_value != MY_INT) {
System.out.println("Got Change for MY_INT :" + MY_INT + "loc:" + local_value);
local_value = MY_INT;
}
}
System.out.println("Change listener");
}
}
}
static class ChangeMaker extends Thread {
@Override
public void run() {
int local_value = MY_INT;
while (MY_INT < 5) {
System.out.println("Incrementing MY_INT to:" + (local_value + 1));
// ! And here
synchronized (MY_INT) {
MY_INT = ++local_value;
}
}
}
}
}