使用Java线程获取和发送消息

时间:2011-09-08 12:18:42

标签: java multithreading

我想创建一个运行的线程,用我给它的数据计算一些东西,并返回一些值或一个对象。该线程是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站点上的信息没有帮助我。我能够创建一个程序,其中包含多个无限运行的线程,但我无法使其与函数一起使用。

2 个答案:

答案 0 :(得分:3)

我建议你使用ExecutorService。它允许您创建一个线程池,您可以将任务传递给它并稍后获得结果。

http://download.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

答案 1 :(得分:3)

由于这是使用Swing GUI,考虑使用创建后台线程的SwingWorker对象(所有代码都在doInBackground方法中运行),然后可以返回最终结果和/或中期结果。有关如何使用它的信息在此处的教程中有详细记录:

Concurrency in Swing

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();
     }
  }