仅检查一个条件的 while true 循环是否线程安全?

Are while true loops that check only for one condition thread safe?

我正在使用 while 循环来检查条件是否为真:

while(Game.gameState != Game.CLOSING)
{
    if(reconnecting)
    {
        time = System.currentTimeMillis();
    }
    else
    {
        while(time + desiredWait > System.currentTimeMillis())
        {
            try{Thread.sleep(5);}catch(InterruptedException e){}
        }

        time += desiredWait;
    }

    synchronized (Game.gameStateLock)//added to circumvent the problem
    {
        if(Game.gameState == Game.INPROGRESS)//problematic condition
        {
            while(true)
            {
                synchronized (Lockstep.nextTurns)
                {
                    if(!Lockstep.nextTurns.isEmpty() || lockstep.currentTurn == 0)
                        break;
                }

                try{Thread.sleep(5);}catch(InterruptedException e){}

                time = System.currentTimeMillis();
            }

            Lockstep.attemptTurn();
        }
    }
}

循环不休​​眠不间断运行(如果reconnecting为真),因此在每个循环中访问Game.gameState(int类型)两次。如果现在在第二个线程中更改了 gameState(例如通过网络),while loop/if 条件不会检测到它并继续拒绝执行 if 块中的代码,即使它应该执行。添加的synchronized(Game.gameStateLock)解决了这个问题。它也很难调试,因为打印 gameState 或其他任何东西都会导致问题不存在。我的猜测是 I/O interrupts/sleeps 线程或导致它 write/read 那么多数据,cpu 的缓存被清除并且 gameState 变量已被读取缓存整个时间必须从 RAM 重新加载。

会不会是这个原因?我假设原始数据类型在处理多线程时不是什么大问题(除非您正在检查一个布尔值然后将其设置为阻塞其他线程)。 Java 中的原始数据类型线程安全吗? (我什至无法同步它们,需要一个虚拟对象)

原始类型不是线程安全的!检查这个:http://i-proving.com/2009/04/23/java-primitive-thread-safety/?showComments=true

"thread safe" 并不是您真正要查找的术语,这可能就是您苦苦挣扎的原因。您的代码在技术上是 "thread safe",因为您不会遇到由于多线程而导致的任何损坏。但是,您缺少的是与 "visibility" 相关的保证。在您的情况下,无法保证一个线程所做的更改将 "visible" 更改为另一个线程。有多种方法可以使更改可见。在您的情况下,使 gameState 易变就足以强制对该值的更改进行跨线程可见性。