我正在编写一个多线程的tic tac toe程序,其中服务器是两个客户端之间的连接。服务器打开并等待连接:第一个连接的客户端是玩家X,第二个是玩家O.玩家可以随时退出游戏,一旦客户端退出,其他客户端将重置其主板并等待新的联系。这部分工作正常,但问题是,一旦我产生了一个新客户端,我会收到以下错误:
java.base /中java.base / java.util.concurrent.locks.ReentrantLock $ Sync.tryRelease(ReentrantLock.java:149)中的线程“pool-1-thread-1”java.lang.IllegalMonitorStateException异常java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1300)位于TicTacToeServer.processMessage的java.base / java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:439)(TicTacToeServer.java: 329)at ticTacToeServer $ Player.run(TicTacToeServer.java:498)at java.base / java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135)at java.base / java.util.concurrent.ThreadPoolExecutor $ Worker .run(ThreadPoolExecutor.java:635)在java.base / java.lang.Thread.run(Thread.java:844)
看来,无论哪个线程被关闭,都会引发此错误。玩家X总是首先连接哪个客户端,所以它总是线程1而玩家O总是线程2.对于上面的错误,我关闭了玩家X并打开了一个新的(线程3)。
每个客户端窗口都有一个允许它们退出的按钮,它使用动作监听器,如下所示:
quitGame = new JButton("Quit");
quitGame.addActionListener(new ActionListener() {
@Override
public void actionPerformed(ActionEvent e) {
System.out.println("Quit button was clicked!");
displayMessage( "You have quit the game.\n" );
output.format("Quit. " + myMark + "\n");
output.flush();
try
{
connection.close(); // close connection to client
System.exit(0);
} // end try
catch ( IOException ioException )
{
ioException.printStackTrace();
System.exit( 1 );
} // end catch
}
});
panel2.add( quitGame, BorderLayout.SOUTH ); // add button to panel
add( panel2, BorderLayout.CENTER ); // add container panel
这对应于服务器中的以下代码:
else if (message.equals("Quit. X")) {
//connection.close(player[PLAYER_X]);
currentPlayer = PLAYER_X;
displayMessage("\nPlayer X has ended the game.\n");
players[1].send("Player X has ended the game.");
players[1].send("Please wait for new player to connect.");
players[(currentPlayer+1)%2].send("Restart.");
players[currentPlayer].send("Restart.");
for(int x = 0;x<board.length;x++)
{
board[x] = "";
numRep[x] = 4;
}// end for loop
try // wait for connection, create Player, start runnable
{
players[ 0 ] = new Player( server.accept(), 0 );
Player temp = players[0];
players[1].send("New player has connected. Game on!");
players[1].send("Please wait for your turn.");
runGame.execute( players[0] ); // execute player runnable
} // end try
catch ( IOException ioException )
{
ioException.printStackTrace();
System.exit( 1 );
} // end catch
//gameLock.lock();
try // allow x to go first
{
players[ PLAYER_X ].setSuspended( false ); // resume player X
otherPlayerConnected.signal(); // wake up player X's thread
} // end try
finally
{
gameLock.unlock(); // unlock game after signaling player X
} // end finally
} // end if
错误中特别提到的行是:
gameLock.unlock(); // unlock game after signaling player X
显示在上面的finally块和
中if ( input.hasNextLine() )
processMessage(input.nextLine()); // get message
在run()中找到并调用processMessage,它处理客户端发送的消息,部分显示在上面。
我一直在试图关闭连接,输入,输出等,但我似乎无法摆脱这个错误。它不影响实际游戏,我假设因为错误是在关闭的线程上,但我仍然想修复它。任何帮助表示赞赏!
答案 0 :(得分:0)
来自ReentrantLock.unlock()
的{{3}}:
如果当前线程不是此锁的持有者那么 抛出IllegalMonitorStateException。
您需要在unlock
之前获取锁定。