Я использую время цикла, что проверка на условие, чтобы стать правдой:В то время как истинные циклы, которые проверяют только на одно условие безопасности потока?
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();
}
}
}
Цикл работает бесперебойно без сна (если переподключения верно), и, следовательно, доступ к Game.gameState (типа Int) два раза в каждом цикле. Если gameState теперь изменяется во втором потоке (например, через сеть), условие while/if не обнаруживает его и продолжает отказываться выполнять код в блоке if, даже если это необходимо. Добавленная синхронизация (Game.gameStateLock) решает эту проблему. Также очень сложно отлаживать, вызывать печать gameState или что-то еще, что приведет к тому, что проблема будет несуществующей. Я предполагаю, что I/O прерывает/спит поток или заставляет его писать/читать много данных, что кеш процессора очищается, а переменная gameState, которая была прочитана из кеша, все время должна быть перезагружена из ОЗУ.
Возможно, это причина? Я предположил, что примитивные типы данных не являются проблемой, связанной с несколькими потоками (если вы не проверяете логическое значение, а затем устанавливаете его для блокировки других потоков). Являются ли примитивные типы данных в потоке Java безопасными? (я даже не могу синхронизировать их, нужен фиктивный объект)
Возникает ли проблема в какой-либо мере, делая игру без изменений? –
Если gameState не определяется как volatile, тогда у вас будет проблема с внешним циклом while. Вы можете получить доступ к его значению, в то время как он может быть установлен одновременно внешним потоком. См. Http://stackoverflow.com/questions/9278764 – mdewit
Так что добавление изменчивости в переменную позволило бы решить мою проблему? – Geosearchef