由ExecutorService及Callable実现有返回值的线程
程序员文章站
2022-03-24 12:37:36
...
需在主线程中开启多个线程并发执行一个任务,然后收集各线程执行返回结果并将最终结果汇总,這时就需要Callable接口。
実現方法為:创建一个类并实现Callable接口,在call方法中实现具体的运算逻辑,并返回计算结果。
具体调用过程:创建一个线程池、一个用于接收返回结果的Future List及 Callable线程実例,使用线程池提交任务并,将线程执行之后的结果保存在Future中,在线程执行结束之后遍历Future List 中的Future对象,在该对象上调用get方法即可以获取到Callable线程任务返回的数據并汇总结果。
例:
import java.util.concurrent.Callable;
/**
* ① 通过Callable接口创建MyCallable线程
*/
public class MyCallable implements Callable<String> {
private String name;
/**
* 通过构造器为线程传递参数,以定义线程的名称
* @param name
*/
public MyCallable(String name){
this.name = name;
}
/**
* Computes a result, or throws an exception if unable to do so.
*
* @return computed result
* @throws Exception if unable to compute a result
*/
@Override
public String call() throws Exception {
return name;
}
}
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* 测试MyCallable
*/
public class TestMyCallable {
public void test() {
// ② 创建一个固定大小为7的线程
ExecutorService pool = Executors.newFixedThreadPool(6);
// ③ 创建多个有返回值的任务列表list
List<Future> taskList = new ArrayList<Future>();
for(int i = 0; i < 6; i++ ){
// ④创建一个有返回值的线程実例
Callable c = new MyCallable(i + " ");
// ⑤提交线程,获取Future对象并将其保存到Future List 中
Future future = pool.submit(c);
System.out.println("Submit a callable thread: "+i);
taskList.add(future);
}
// ⑥ 关闭线程池,等待线程执行结束
pool.shutdown();
// ⑦ 遍历所有线程的运行结果
taskList.forEach(future -> {
//从Future对象中获取任务返回值,并将结果输出于控制台。
System.out.println("Get the resullt from callable thread: " +
futureGet(future)
);
});
}
private <E extends Exception> String futureGet(Future future) throws E{
try {
return future.get().toString();
} catch (Exception e) {
throw (E) e;
}
}
}