首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在java中后台运行线程

在java中后台运行线程
EN

Stack Overflow用户
提问于 2012-08-30 09:21:17
回答 2查看 5.4K关注 0票数 0

我正在用java写一个国际象棋程序。到目前为止,一切都很顺利,但我在更新UI时确实遇到了问题。

下面是扩展JPanel的类ChessBoard的代码片段。当用户尝试进行移动时,将调用此函数:

代码语言:javascript
复制
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更新,以反映用户的移动,然后运行算法。这就是为什么我在单独的线程上运行算法的原因。但我的用户界面不会被更新,直到电脑也有了动作。

因此,如果用户点击一个空间来发送一件作品,屏幕就会冻结,然后突然之间这件作品移动了,但计算机也移动了,再次轮到玩家了。

任何帮助都将不胜感激。

EN

回答 2

Stack Overflow用户

发布于 2012-08-30 09:25:38

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

Relevant JavaDoc

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

票数 4
EN

Stack Overflow用户

发布于 2012-08-30 09:33:51

首先,线程不是可重入的(我稍后会解释这一点)。

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

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

代码语言:javascript
复制
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方法完成,Thread的实例就不能重新启动。

因此,多次使用thread.start()而不是一次将不起作用(我不记得它是否抛出异常)(这就是我更喜欢Runnable的原因)

所以。你想做的是,当你的程序加载时启动Thread,当你需要的时候,调用thread.doNextMove()让它计算你所需要的东西。

现在,还要记住,Swing并不是Thread安全的。也就是说,您不应该从Event Dispatching Thread (或EDT)以外的任何Thread更新UI。

您可能还想通读一下Concurrency in Swing

哦,还有Concurrency in Java

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/12188659

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档