上一篇中Runable是独立线程,它不会存在线程返回值的问题,但是在实际项目中可能就需要返回值。下文是我看《Thinking in Java》一书时的笔记。
为获取线程返回值,对应的线程类需要实现 Callable 接口。下面是一个示例
public class TaskWithResult implements Callable<String> {
protected int countDown = 100000;
private static int taskCount = 0;
private final int id = taskCount++;
public TaskWithResult() {}
public TaskWithResult(int countDown) {
this.countDown = countDown;
}
@Override
public String call() throws Exception {
while (countDown-- > 0) {
Thread.yield();
}
return String.valueOf(id);
}
}
下面的代码是的调用示例:
private static void testCallable() {
ExecutorService executorService = Executors.newCachedThreadPool();
ArrayList<Future<String>> results = new ArrayList<Future<String>>();
for (int i = 0; i < 10; i++) {
results.add(executorService.submit(new TaskWithResult()));
}
ArrayList<Future<String>> tmpList = new ArrayList<Future<String>>();
while (true) {
for (Future<String> fsFuture : results) {
try {
if (fsFuture.isDone()) {
// 如果线程done,就调用get函数获取返回值。
System.out.println(fsFuture.get());
// 并将完成的线程加入到tmplist中,便于在for循环后删除。
tmpList.add(fsFuture);
}
} catch (Exception e) {
} finally {
executorService.shutdown();
}
}
// 删除done的线程。
results.removeAll(tmpList);
tmpList.clear();
// 如果所有的线程都done,就退出程序。
if (0 == results.size()) {
break;
}
}
}
Callable接口需要和Future结合使用才能获取返回值。
ExecutorService.submit函数会返回一个Future 对象,可以调用Future.isDone函数Future是否完成。如果完成,接下来就可以调用Future.get函数获取线程返回值。