【问题标题】:Multithreaded IllegalMonitorStateException多线程 IllegalMonitorStateException
【发布时间】: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


    【解决方案1】:

    来自ReentrantLock.unlock()doc

    如果当前线程不是这个锁的持有者,那么 抛出 IllegalMonitorStateException。

    您需要在unlock之前获取锁。

    【讨论】:

    • 新线程/播放器还是已关闭的线程/播放器?另外我该如何获取锁?我以为它只是为了游戏而存在
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-03-13
    • 2023-03-05
    • 1970-01-01
    • 2018-11-02
    • 1970-01-01
    • 2021-04-22
    相关资源
    最近更新 更多