【发布时间】:2018-05-06 02:17:15
【问题描述】:
我正在编写一个多线程井字游戏程序,其中服务器是两个客户端之间的连接。服务器打开并等待连接:第一个连接的客户端是玩家 X,第二个是玩家 O。玩家可以随时退出游戏,一旦客户端退出,另一个客户端会重置其棋盘并等待新的连接。这部分工作正常,但问题是,一旦我生成一个新客户端,我就会收到以下错误:
java.base/java.util.concurrent.locks.ReentrantLock$Sync.tryRelease(ReentrantLock.java:149) at java.base/的线程“pool-1-thread-1”java.lang.IllegalMonitorStateException 中的异常/ java.util.concurrent.locks.AbstractQueuedSynchronizer.release(AbstractQueuedSynchronizer.java:1300) 在 java.base/java.util.concurrent.locks.ReentrantLock.unlock(ReentrantLock.java:439) 在 TicTacToeServer.processMessage(TicTacToeServer.java: 329) 在 TicTacToeServer$Player.run(TicTacToeServer.java:498) 在 java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1135) 在 java.base/java.util.concurrent.ThreadPoolExecutor$Worker .run(ThreadPoolExecutor.java:635) at 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,处理客户端发送的消息,如上图部分展示。
我一直在尝试关闭连接、输入、输出等,但我似乎无法摆脱这个错误。它不会影响实际游戏,我假设是因为错误出现在已关闭的线程上,但我仍然想修复它。任何帮助表示赞赏!
【问题讨论】:
标签: java multithreading swing runtime-error illegalstateexception