在java中的后台运行线程
我正在用java写一个国际象棋程序。到目前为止,事情进展良好,但我更新我的用户界面时遇到问题。在java中的后台运行线程
这里的代码延伸JPanel类器ChessBoard片段。
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
}
线程呼吁我的棋盘实例“运行”:这是当用户试图使一招叫。发现移动的算法可能需要几秒钟才能决定移动。
我想为我的UI更新以反映用户的举动,然后运行该算法。这就是为什么我在一个单独的线程上运行算法。但是我的用户界面并没有被更新,直到电脑也开始移动。
因此,如果用户点击一个空间,以发送一条那里,屏幕冻结,然后突然一块已经被移动,但计算机移动也并再次是玩家的回合。
任何帮助将不胜感激。
thread.run()
会在线程的run方法执行当前线程的代码。你需要thread.start()
。
重绘方法实际上并没有立即重新绘制。它基本上告诉JPanel它应该很快重新绘制。然后你继续使用同一个线程并计算AI的移动,这将会冻结窗口,因为Swing不是多线程的。
我想你可能想重新考虑这个答案(来自OP的片段)。从[Java文档](http://docs.oracle.com/javase/7/docs/api/java/lang/Thread.html#start%28%29)“*更多地启动线程永远不合法特别是,一旦线程完成执行后,线程可能不会重新启动*“ – MadProgrammer
@MadProgrammer尽管您说的是有效的,但是1)OP的主要问题”停止“行为恰恰是由run( )方法,以及2)从代码片段中,我们没有线索OP是否正在重用线程实例。 OP有可能在if-block之外实例化线程 –
@MadProgrammer正如Adrian所说,这里唯一保证的问题是基于他的代码,这是他调用了错误的方法。 JavaDoc的一部分将他与他联系起来,明确指出你不能多次启动线程,所以如果他阅读答案,他也会认为这一部分也是。 –
首先,线程不重入(我将解释在某一时刻)。
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
s为不可重入,这意味着一旦run方法有完整的Thread
的该实例无法重新启动。
因此,使用thread.start()
,曾多次将无法正常工作(不记得,如果它抛出一个异常或不)(因此我更喜欢Runnable
的原因)
所以。你想要做的是,当你的程序加载时,启动Thread
,当你需要时,请致电thread.doNextMove()
,让它计算出你需要的东西。
现在还记得,Swing
不Thread
安全。也就是说,你永远不应该从不是Event Dispatching Thread(或EDT)其他
您也可能想通过Concurrency in Swing
读你肯定然后将任何
Thread
更新UI需要很长时间才能运行的代码在线程中?或者它在'generateMoves(0)'中?只需几秒钟就可以找到一个调试器。 – Strelok