FutureTask用法
FutureTask可用于异步获取执行结果或取消执行任务的场景。通过传入Runnable或者Callable的任务给FutureTask,直接调用其run方法或者放入线程池执行,之后可以在外部通过FutureTask的get方法异步获取执行结果,因此,FutureTask非常适合用于耗时的计算,主线程可以在完成自己的任务后,再去获取结果。另外,FutureTask还可以确保即使调用了多次run方法,它都只会执行一次Runnable或者Callable任务,或者通过cancel取消FutureTask的执行等。
单线程:
// 创建任务集合
// 创建线程池
// 创建子线程,加入任务集合
// 提交任务到线程池
// 获取任务结果
// 关闭线程池
public class FutureTaskTest {
public static void main(String[] args) throws InterruptedException,
ExecutionException {
// 创建线程池
ExecutorService es = Executors.newFixedThreadPool(5);
// 创建子线程,加入任务集合
FutureTask<Integer> ft = new FutureTask<Integer>(
new FutureTaskTest().new Task(0, "1"));
// 提交任务到线程池
es.submit(ft);
// 获取任务结果
System.out.println("线程计算结果" + ft.get());
// 关闭线程池
es.shutdown();
}
// 实现Callable接口,创建子线程,打印0-5之和
private class Task implements Callable<Integer> {
private Integer result = 0;
private String taskName = "";
public Task(Integer result, String taskName) {
super();
this.result = result;
this.taskName = taskName;
System.out.println("正在生成子线程:" + taskName);
}
public Integer getResult() {
return result;
}
public String getTaskName() {
return taskName;
}
@Override
public Integer call() throws Exception {
// TODO Auto-generated method stub
for (int i = 0; i <= 5; i++) {
result += i;
}
System.out.println("线程 " + taskName + " 的结果是" + result);
return result;
}
}
}
多线程:
// 创建任务集合
// 创建线程池
// 创建子线程,加入任务集合
// 提交任务到线程池
// 获取任务结果
// 关闭线程池
public class FutureTaskMulitCompute {
public static void main(String[] args) {
//
FutureTaskMulitCompute inst = new FutureTaskMulitCompute();
// 创建任务集合
ArrayList<FutureTask<Integer>> taskList = new ArrayList<FutureTask<Integer>>();
// 创建 线程池重用固定数量的线程,操作一个共享的无界队列
ExecutorService exec = Executors.newFixedThreadPool(5);
// 创建10个线程,加入tackList任务集合
for (int i = 0; i < 5; i++) {
// 传入Callable创建FutureTask对象
FutureTask<Integer> ft = new FutureTask<Integer>(
inst.new ComputeTask(i, "" + i));
// 加入taskList任务集合
taskList.add(ft);
// 提交线程池任务,
exec.submit(ft);
// exec.invokeAll(taskList);//一次提交所有任务
}
System.out.println("所有计算任务提交完毕,主线程接着干其他事情");
// 开始统计各线程计算结果
Integer totalResult = 0;
for (FutureTask<Integer> ft : taskList) {
try {
totalResult += ft.get();
} catch (InterruptedException | ExecutionException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
// 关闭线程池
exec.shutdown();
System.out.println("多任务计算结果:" + totalResult);
}
private class ComputeTask implements Callable<Integer> {
private Integer result = 0;
private String taskName = "";
public ComputeTask(Integer result, String taskName) {
super();
this.result = result;
this.taskName = taskName;
System.out.println("生成子线程:" + taskName);
}
public Integer getResult() {
return result;
}
public String getTaskName() {
return taskName;
}
@Override
public Integer call() throws Exception {
// TODO Auto-generated method stub
for (int i = 0; i < 10; i++) {
result = i;
}
Thread.sleep(1000);// 休眠1s
System.out.println("子线程:" + taskName + ",执行结果:" + result);
return result;
}
}
}