Java IF语句仅在其';s前面有一个';sysout';它所测试的价值
我犯了一个很奇怪的错误。我有以下代码:Java IF语句仅在其';s前面有一个';sysout';它所测试的价值,java,multithreading,if-statement,Java,Multithreading,If Statement,我犯了一个很奇怪的错误。我有以下代码: while (true) { System.out.println(model.getLightState()); if (model.getLightState() == 1) { System.out.println("Entered.."); view.driveThroughJunction(); break; } } 现在,当灯光状态变为“1”时,我的程序会输入if语句,并
while (true) {
System.out.println(model.getLightState());
if (model.getLightState() == 1) {
System.out.println("Entered..");
view.driveThroughJunction();
break;
}
}
现在,当灯光状态变为“1”时,我的程序会输入if语句,并执行代码。但这只有在进入while循环后有print-out语句时才有效。我觉得很奇怪。“sysout”行会对if语句产生任何影响吗?显然,对于上述情况是这样的
你知道为什么会这样吗
编辑:
您有同步问题,导致可见性问题。如果在读取和写入多个线程共享的变量时未使用同步,则无法保证一个线程写入的值对其他线程可见 要解决此问题,您需要执行以下操作之一:
- 使
字段状态
可变
- 将
字段类型更改为状态
原子整数
- 同步对
字段的每次访问(使用状态
关键字),当然每次都使用相同的锁synchronized
sysout调用使该值可见,因为它在内部调用了将寄存器状态刷新到主存的方法(例如,通过写入易失性字段或调用同步方法)。出现同步问题,从而导致可见性问题。如果在读取和写入多个线程共享的变量时未使用同步,则无法保证一个线程写入的值对其他线程可见 要解决此问题,您需要执行以下操作之一:
- 使
字段状态
可变
- 将
字段类型更改为状态
原子整数
- 同步对
字段的每次访问(使用状态
关键字),当然每次都使用相同的锁synchronized
sysout调用使该值可见,因为它在内部调用了将寄存器状态刷新到主内存的方法(例如,通过写入易失性字段或调用同步方法)。您应该将模型实例声明为易失性 Java中的Volatile关键字被用作Java编译器和线程的指示符,Java编译器和线程不缓存该变量的值,并且总是从主内存中读取它。所以,如果您想通过实现共享读写操作是原子的任何变量,您应该将它们声明为volatile变量 阅读更多:
从您的评论中可以明显看出,有多个线程正在访问同一个模型实例并在同一个模型实例中执行读/写操作。如果没有volatile,线程会缓存模型实例的值,从而导致脏读。随着
System.out.println
的发生,您的读/写操作会延迟一点(由于输出写入),因此线程能够从主存刷新缓存值。您应该将模型实例声明为volatile
Java中的Volatile关键字被用作Java编译器和线程的指示符,Java编译器和线程不缓存该变量的值,并且总是从主内存中读取它。所以,如果您想通过实现共享读写操作是原子的任何变量,您应该将它们声明为volatile变量
阅读更多:
从您的评论中可以明显看出,有多个线程正在访问同一个模型实例并在同一个模型实例中执行读/写操作。如果没有volatile,线程会缓存模型实例的值,从而导致脏读。当
System.out.println
发生时,您的读/写操作会延迟一点(由于输出写入),因此线程能够从主内存刷新缓存值。您是否在getLightState
中更改任何内容?向我们展示您的getLightState()
。您是否碰巧在一个单独的线程中运行此代码?能否尝试将模型实例声明为volatile?@anubhava成功了!请你提供一个答案并解释一下。谢谢。您是否在getLightState
中更改了任何内容?向我们展示您的getLightState()
。您是否碰巧在单独的线程中运行此代码?是否可以尝试将模型实例声明为volatile?@anubhava成功了!请你提供一个答案并解释一下。谢谢。使模型不稳定并不能解决问题——他正在访问另一个变量。如果它真的解决了问题,那纯粹是巧合。另一个答案是正确的。也许你能更好地解释这个纯粹的巧合理论。顺便说一句,另一个答案也建议使用volatile变量。使model
volatile只会保证如果您编写model=newmodel()代码>它将被其他线程看到。它不能保证对其字段的更改是可见的。换句话说,它不能保证model.state=someNewState代码>将从另一个线程可见。另一个答案建议在state
变量上使用volatile。使模型变为volatile并不能解决问题-他正在访问另一个变量。如果它真的解决了问题,那纯粹是巧合。另一个答案是正确的。也许你能更好地解释这个纯粹的巧合理论。顺便说一句,另一个答案也建议使用volatile变量。使model
volatile只会保证如果您编写model=newmodel()代码>它将被其他线程看到。它不能保证对其字段的更改是可见的。换句话说,它不能保证model.state=someNewState代码>将从另一个线程可见。另一个答案建议在<代码上使用volatile
(in the model class)
public final byte getLightState() {
return lightChanger.getLightValue();
}
(in lightchanger class)
public byte getLightValue() {
return light.getState();
}
(in the light class)
public final byte getState() {
return this.state;
}