我想创建一个运行的线程,用我给它的数据计算一些东西,并返回一些值或一个对象。该线程是Swing GUI的一部分。
我的问题:如何创建一个在我创建线程时运行的方法,并返回一个对象(或者我希望它返回的任何对象)?
我的代码:
private void nextTurn () {
// do something
if (turn == white) {
try {
Engine e = new Engine(); // Engine is implemented by runnable
e.start();
Move m = e.getBestMove (board);
// thread should work, next code should be excecuted immediately
}
catch (Exception e) {}
}
// end of Main class
}
这是我第一次使用Threads,我知道如果可能的话你应该避免使用它们,但这次我的GUI需要它。 线程上的Oracle站点上的信息没有帮助我。我能够创建一个程序,其中包含多个无限运行的线程,但我无法使其与函数一起使用。
答案 0 :(得分:3)
我建议你使用ExecutorService。它允许您创建一个线程池,您可以将任务传递给它并稍后获得结果。
http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html
答案 1 :(得分:3)
由于这是使用Swing GUI,考虑使用创建后台线程的SwingWorker
对象(所有代码都在doInBackground
方法中运行),然后可以返回最终结果和/或中期结果。有关如何使用它的信息在此处的教程中有详细记录:
SwingWorkers具有属性更改支持,因此允许侦听器通过PropertyChangeListener观察其状态(作为SwingWorker.StateValue)。这是程序可以确定线程已完成其处理,获取返回结果并从那里开始的一种方式。
在一个不相关的说明中,这不是你的生产代码吗?:
catch (Exception e) {}
如果是这样,你可能会想要解决这个问题,因为被忽略的异常可能会让你陷入困境。
如,
if (turn == white) {
try {
final SwingWorker<Move, Void> mySwingWorker = new SwingWorker<Move, Void>() {
@Override
protected Move doInBackground() throws Exception {
Engine e = new Engine(); // Engine is implemented by runnable
e.start();
Move m = e.getBestMove(board);
return m;
}
};
mySwingWorker.addPropertyChangeListener(new PropertyChangeListener() {
public void propertyChange(PropertyChangeEvent evt) {
if (StateValue.DONE == mySwingWorker.getState()) {
try {
Move m = mySwingWorker.get();
// TODO: insert code to run on the EDT after move determined
} catch (InterruptedException e) {
e.printStackTrace();
} catch (ExecutionException e) {
e.printStackTrace();
}
}
}
});
mySwingWorker.execute();
} catch (Exception e) {
e.printStackTrace();
}
}