在java中的背景中运行线程

时间:2012-08-30 01:21:17

标签: java multithreading user-interface background chess

我正在用java编写国际象棋程序。到目前为止,事情进展顺利,但我确实更新了我的UI。

这是ChessBoard类的代码片段,它扩展了JPanel。当用户尝试移动时调用此方法:

if ( isLegalMove( aMove ) ) { // If the move's legal
    makeMove( aMove ); // Make that move
    select = null; // Reset some info
    drag = null;
    toggleTurn(); // Change turns
    generateMoves( 0 ); // Get legal moves for CPU
    repaint(); // Redraw board
    thread.run(); // Run chess algorithm
}

线程在我的ChessBoard实例上调用“run”。找到移动的算法可能需要几秒钟来决定移动。

我希望我的UI更新以反映用户的移动,然后运行算法。这就是我在一个单独的线程上运行算法的原因。但是直到计算机也采取行动之前我的UI才会更新。

因此,如果用户点击一个空间在那里发送一块,那么屏幕就会冻结,然后突然间该块已经移动但是计算机也已经移动了,这又是玩家的回合。

非常感谢任何帮助。

2 个答案:

答案 0 :(得分:4)

thread.run()将在当前线程的线程的run方法中执行代码。你想要thread.start()

Relevant JavaDoc

重绘方法实际上不会立即重绘。它基本上告诉JPanel它应该很快重绘自己。然后你继续在相同的线程上计算AI的移动,这将冻结窗口,因为Swing不是多线程的。

答案 1 :(得分:1)

首先,线程不可重入(我稍后会解释)。

thread.run()不会导致线程在单独的线程中执行,它只是调用线程的run方法(在当前Thread的上下文中。

您需要做的是在Thread中设置一个可以触发的条件循环,以便执行您需要的逻辑。

public class ChessThread extends Thread { // I prefer Runnable, that's me
    protected static final Object NEXT_MOVE_LOCK = Object();

    public ChessThread() {
        setDaemon(true); // This will allow the JVM to exit without the need to terminate the thread...
    }

    public void doNextMove() {
        // Notify the "wait" that we want to continue calculating the next move
        synchronized (NEXT_MOVE_LOCK) {
            NEXT_MOVE_LOCK.notify();
        }
    }       

    public void run() { 
        while (true) {
            // Wait for the "next move" request
            synchronized (NEXT_MOVE_LOCK) {
                try {
                    NEXT_MOVE_LOCK.wait();
                } catch (InterruptedException exp) {
                }
            }
            // Calculate the next move...
        }
    }
}

现在,Thread是不可重入的,这意味着一旦run方法完成,就无法重新启动Thread的该实例。

因此使用thread.start()多次一次将无效(不记得是否抛出异常)(因此我更喜欢Runnable

因此。您想要做的是,在程序加载时以及需要时启动Thread,调用thread.doNextMove()以使其计算您需要的内容。

现在,请记住,Swing不是Thread安全的。也就是说,您不应该从Event Dispatching Thread(或EDT)以外的任何Thread更新用户界面

您可能还希望阅读Concurrency in Swing

哦和Concurrency in Java