Future 机制简介
Java 的 Future 接口是执行异步任务的核心。当我们运行的任务需要较长时间,我们不想要等待它执行完才能去做其他任务时,可以使用异步任务。
比如我们执行任务A,B,C,每个任务执行时间要1s,串行执行时,执行完三个任务大概要3s;使用异步任务,把任务A、B、C都添加到线程池中,交给线程池里的线程执行,在主线程调用 FutureTask.get() 方法获取任务执行的结果,如果任务未执行或在执行中,线程会阻塞,如果任务执行完,会返回执行结果或抛异常,执行完三个任务大概要1s。
代码示例
@Test
public void FutureTaskTest(){
Instant start = Instant.now();
int res = add(1, 2) + add(3, 4) + add(5, 6);
Instant end = Instant.now();
log.info("运行结果:{},运行时间:{}",res,end.toEpochMilli() - start.toEpochMilli());
}
//模拟耗时任务
public int add(int i, int j) {
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return i + j;
}
运行结果:21,运行时间:3001
@Test
public void FutureTaskTest(){
//创建线程池
ExecutorService executorService = Executors.newFixedThreadPool(3);
Instant start = Instant.now();
//创建任务交给线程池里的线程执行
Future<Integer> calculateTask1 = executorService.submit(new CalculateTask(1,2));
Future<Integer> calculateTask2 =executorService.submit(new CalculateTask(3, 4));
Future<Integer> calculateTask3 =executorService.submit(new CalculateTask(5, 6));
int res = 0;
try {
//异步获取结果
res = calculateTask1.get(30, TimeUnit.MINUTES) +calculateTask2.get(30, TimeUnit.MINUTES) +calculateTask3.get(30, TimeUnit.MINUTES);
} catch (Exception e) {
e.printStackTrace();
}
Instant end = Instant.now();
log.info("运行结果:{},运行时间:{}",res,end.toEpochMilli() - start.toEpochMilli());
}
//模拟耗时任务,实现 Callable 接口,call方法里实现任务逻辑
private class CalculateTask implements Callable<Integer> {
private int i;
private int j;
public CalculateTask(int i,int j){
this.i = i;
this.j = j;
}
@Override
public Integer call(){
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return i + j;
}
}
运行结果:21,运行时间:1003