Ich bin eine while-Schleife verwenden, die für eine Bedingung überprüft zu werden wahr:Sind während True Loops, die nur für eine Bedingung thread sicher sind?
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();
}
}
}
Die Schleife, ohne schlafen ununterbrochen läuft (wenn reconnecting wahr ist), und daher greift Game.gameState (vom Typ int) zweimal in jedem Zyklus. Wenn gameState nun in einem zweiten Thread geändert wird (z. B. über ein Netzwerk), erkennt die while-Schleife/if-Bedingung dies nicht und weigert sich weiterhin, den Code im if-Block auszuführen, selbst wenn dies der Fall ist. Die hinzugefügte Synchronisierung (Game.gameStateLock) löst dieses Problem. Es ist auch sehr schwer zu debuggen, weil das Drucken des Spielstatus oder irgendetwas anderes dazu führt, dass das Problem nicht existiert. Meine Vermutung ist, dass I/O den Thread unterbricht/unterbricht oder veranlasst, dass so viele Daten geschrieben/gelesen werden, dass der Cache der CPU gelöscht wird und die Variable gameState, die die ganze Zeit aus dem Cache gelesen wurde, neu geladen werden muss RAM.
Kann dies der Grund sein? Ich nahm an, dass primitive Datentypen im Umgang mit mehreren Threads kein großes Problem darstellen (es sei denn, Sie überprüfen einen booleschen Wert und setzen ihn dann so, dass er andere Threads blockiert). Sind primitive Datentypen in Java threadsicher? (Ich kann nicht einmal auf ihnen synchronisieren, benötigt ein Dummy-Objekt)
Entwickelt sich das Problem in irgendeiner Weise, indem GameState instabil wird? –
Wenn GameState nicht als flüchtig definiert ist, dann haben Sie ein Problem mit Ihrer äußeren while-Schleife. Sie könnten auf seinen Wert zugreifen, während er gleichzeitig von einem externen Thread gesetzt werden könnte. Siehe http://StackOverflow.com/Questions/9278764 – mdewit
Also hinzufügen volatile zu der Variable würde mein Problem lösen? – Geosearchef