线程在完成工作后如何返回一个值?

假设我们有这个简单的例子:

public Example extends Thread{ String temp; public Example(){ } @Override public void run(){ . . . . temp = "a_value"; } public static void main(String[] args) { Example th = new Example(); th.start(); } } 

线程完成工作之后怎样才能让我返回String temp?

使用(相对)新的Callable<T>而不是Runnable(在1.5和更新的版本中可用):

这是一个(简单的)例子:

 import java.util.concurrent.Callable; import java.util.concurrent.ExecutionException; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.Future; public class Main { public static void main(final String[] argv) { final ExecutorService service; final Future<String> task; service = Executors.newFixedThreadPool(1); task = service.submit(new Foo()); try { final String str; // waits the 10 seconds for the Callable.call to finish. str = task.get(); // this raises ExecutionException if thread dies System.out.println(str); } catch(final InterruptedException ex) { ex.printStackTrace(); } catch(final ExecutionException ex) { ex.printStackTrace(); } service.shutdownNow(); } } class Foo implements Callable<String> { public String call() { try { // sleep for 10 seconds Thread.sleep(10 * 1000); } catch(final InterruptedException ex) { ex.printStackTrace(); } return ("Hello, World!"); } } 

看看未来的界面javadoc。 它有示例用法,告诉你如何做到这一点。

您可以通过观察者模式实现此目的。 在完成线程通知所有的听众,它已完成,他们可以检索的价值(通过获得)。 或者它甚至可以发送计算的值。

或者您可以使用任务,请参阅FutureTask ,一个可运行的(实际上如Callable所述),返回结果并可以抛出exception。

如果您不想交换解决scheme以使用Callable对象,那么您也可以使用队列并以这种方式从线程返回结果。
我重新写你的例子是这样的:

 import java.util.PriorityQueue; import java.util.Queue; public class GetResultFromThread { public static void main(String[] args) throws Exception { Queue<String> queue = new PriorityQueue<String>(); int expectedResults = 2; for (int i = 0; i < expectedResults; i++) { new Example(queue).start(); } int receivedResults = 0; while (receivedResults < expectedResults) { if (!queue.isEmpty()) { System.out.println(queue.poll()); receivedResults++; } Thread.sleep(1000); } } } class Example extends Thread { private final Queue<String> results; public Example(Queue<String> results) { this.results = results; } @Override public void run() { results.add("result from thread"); } } 

请注意,你应该想到同步和并发!