我对JAVA很新,特别是并发,所以很可能/希望这是一个相当直接的问题。
基本上从我的主线程中我得到了:
public void playerTurn(Move move)
{
// Wait until able to move
while( !gameRoom.game.getCurrentPlayer().getAllowMove() )
{
try {
Thread.sleep(200);
trace("waiting for player to be available");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
gameRoom.getGame().handle(move);
}
gameRoom.getGame()在自己的线程上。 gameRoom.getGame()。handle()是同步的 gameRoom.game.getCurrentPlayer()在gameRoom.getGame()的变量上,它在同一个线程中
调用handle(move)后,allowMoves设置为false,一旦处理完移动,就会返回true。
我多次调用playerTurn()。我实际上是从SmartFoxServer扩展中调用它,当它收到请求时,通常是快速连续的。
我的问题是,大部分时间都有效。然而,有时它会发出多个句柄(移动)调用,即使allowMoves应该为false。它不再等待它再次成真。我认为游戏线程可能在调用另一个句柄(移动)之前没有机会设置allowMoves。我将volatile添加到allowMoves,并确保游戏线程上的函数设置为synchronized。但问题仍然存在。
这些在我的游戏课程中:
synchronized public void handle(Object msg)
{
lastMessage = msg;
notify();
}
synchronized public Move move() throws InterruptedException
{
while (true)
{
allowMoves = true;
System.out.print(" waiting for move()...");
wait();
allowMoves = false;
if (lastMessage instanceof Move)
{
System.out.print(" process move()...");
Move m = (Move) lastMessage;
return m;
}
}
}
public volatile boolean allowMoves;
synchronized public boolean getAllowMoves()
{
return allowMoves;
}
正如我所说,我是新手,并且可能比我自己领先一点(按照惯例,但是我的风格是跳到深层,无论如何都很适合快速学习曲线。)
为你的帮助干杯。
答案 0 :(得分:1)
问题是你在两个不同的对象上使用synchronized
方法。
gameRoom.game.getCurrentPlayer().getAllowMove()<-- This is synchronized on
CurrentPlayer instance.
gameRoom.getGame().handle(move)<-- This is synchronized on `gameRoom.getGame()`
这是你的问题。您synchronized
不需要getAllowMoves
个关键字,因为字段为volatile
,因为volatile
保证了可见性语义。
public boolean getAllowMoves() {
return allowMoves;
}
答案 1 :(得分:1)
不确定这是否有帮助,但如果您使用AtomicBoolean代替synchronized
和volatile
会怎样?它说它是lock-free and thread-safe
。
答案 2 :(得分:0)