gpt4 book ai didi

java - 仅检查一个条件的 while true 循环线程安全吗?

转载 作者:行者123 更新时间:2023-12-01 09:37:51 25 4
gpt4 key购买 nike

我正在使用 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();
}
}
}

循环不间断地运行,不会 hibernate (如果重新连接为 true),因此在每个周期中访问 Game.gameState(int 类型)两次。如果现在在第二个线程中更改 gameState(例如通过网络),则 while 循环/if 条件不会检测到它,并且即使应该执行,也会继续拒绝执行 if block 中的代码。添加的synchronized(Game.gameStateLock)解决了这个问题。它也很难调试,因为打印 gameState 或其他任何东西都会导致问题不存在。我的猜测是,I/O 中断/hibernate 线程或导致其写入/读取大量数据,CPU 的缓存被清除,并且一直从缓存读取的 gameState 变量必须从内存。

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

最佳答案

“线程安全”并不是您正在寻找的术语,这可能就是您苦苦挣扎的原因。您的代码在技术上是“线程安全的”,因为您不会因多线程而遇到任何损坏。然而,您缺少的是与“可见性”相关的保证。在您的情况下,无法保证一个线程所做的更改对另一个线程“可见”。有多种方法可以使更改可见。在您的情况下,使 gameState volatile 足以强制对该值的更改进行跨线程可见性。

关于java - 仅检查一个条件的 while true 循环线程安全吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38703663/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com