假设我们有这个简单的例子:
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?
答案 0 :(得分:65)
使用(相对)新的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!");
}
}
答案 1 :(得分:12)
查看Future接口javadoc。它有示例用法,向您展示如何执行此操作。
答案 2 :(得分:8)
您可以通过Observer模式实现此目的。 在完成线程时通知所有听众它已完成并且他们可以检索值(通过getter)。或者它甚至可以发送计算值。
或者你可以使用一个任务,参见FutureTask,一个runnable(确实如下面一个Callable所述),它返回一个结果并且可以抛出异常。
答案 3 :(得分:0)
如果您不想交换解决方案以使用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");
}
}
请注意,您应该考虑同步和并发!