我有以下代码:
public class Simulation
{
public static volatile boolean IS_EVEN_TICK;
}
以及另一个(runnable)类中的以下内容:
public void run()
{
while (true)
{
// flip the "even/uneven tick" switch
Simulation.IS_EVEN_TICK = !Simulation.IS_EVEN_TICK;
}
}
据我所知,这通常不是线程安全的,因为对Simulation.IS_EVEN_TICK的写入取决于该变量的当前值。但是这个线程是唯一写入变量的线程,所有其他线程只会读取变量(如果它们完全访问它)。
变量是否足够易变,以确保所有线程从中读取正确的值,或者我是否需要同步对变量的访问?
答案 0 :(得分:6)
然而,这个线程是唯一写入变量的线程......变量是否足够易变,以确保所有线程都从中读取正确的值。
如果只有一位作家,则没有竞争条件。您不需要跨变量进行同步。
您可以考虑使用AtomicBoolean
,但它不支持toggle()
方法,因此如果您有多个编写者切换值,则必须执行以下操作:
private final AtomicBoolean isEvenTick = new AtomicBoolean();
...
boolean currentValue;
do {
currentValue = isEvenTick.get();
} while (!isEvenTick.compareAndSet(currentValue, !currentValue);
答案 1 :(得分:0)
尝试阅读specification并理解JMM,如果你的变量volatile
意味着变量将直接在堆中创建,并且没有一个处理器不会将该值复制到自己的缓存中。
易失性字段是用于在线程之间传递状态的特殊字段。每次读取volatile都会看到任何线程对该volatile的最后一次写入;实际上,它们被程序员指定为字段,因为缓存或重新排序而无法接受“陈旧”值