文章目录
FutureTask概述
FutureTask代表了一个可被取消的异步计算任务,该类实现了Future接口,比如提供了启动和取消任务、查询任务是否完成、获取计算结果的接口。 FutureTask任务的结果只有当任务完成后才能获取,并且只能通过get系列方法获取,当结果还没出来时,线程调用get系列方法会被阻塞。另外,一旦任务被执行完成,任务将不能重启,除非运行时使用了runAndReset方法。FutureTask中的任务可以是Callable类型,也可以是Runnable类型(因为FutureTask实现了Runnable接口),FutureTask类型的任务可以被提交到线程池执行。
使用实例
public static String doSomethingA() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("--- doSomethingA---");
return "TaskAResult";
}
public static String doSomethingB() {
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("--- doSomethingB---");
return "TaskBResult";
}
public static void main(String args[]) throws ExecutionException, InterruptedException {
long start = System.currentTimeMillis();
// 1.创建future任务
FutureTask<String> futureTask = new FutureTask<String>(() -> {
String result = null;
try {
result = doSomethingA();
} catch (Exception e) {
e.printStackTrace();
}
return result;
});
// 2.开启异步单元执行任务A
Thread thread = new Thread(futureTask, "threadA");
thread.start();
// 3.执行任务B
String taskBResult = doSomethingB();
// 4.同步等待线程A运行结束
String taskAResult = futureTask.get();
// 5.打印两个任务执行结果
System.out.println(taskAResult + " " + taskBResult);
System.out.println(System.currentTimeMillis() - start);
}
}

使用main线程执行任务doSomethingB,这时候任务doSomethingB和doSomethingA是并发运行的,等main函数运行doSomethingB完毕后,同步等待doSomethingA任务完成,然后代码5打印两个任务的执行结果。 ·如上可知使用FutureTask可以获取到异步任务的结果。当然我们也可以把FutureTask提交到线程池来执行,使用线程池运行方式的代码如下:
// 0自定义线程池
private final static int AVALIABLE_PROCESSORS = Runtime.getRuntime().availableProcessors();
private final static ThreadPoolExecutor POOL_EXECUTOR = new ThreadPoolExecutor(AVALIABLE_PROCESSORS,
AVALIABLE_PROCESSORS * 2, 1, TimeUnit.MINUTES, new LinkedBlockingQueue<>(5),
new ThreadPoolExecutor.CallerRunsPolicy());
public static void main(String[] args) throws InterruptedException, ExecutionException {
long start = System.currentTimeMillis();
// 1.创建future任务
FutureTask<String> futureTask = new FutureTask<String>(() -> {
String result = null;
try {
result = doSomethingA();
} catch (Exception e) {
e.printStackTrace();
}
return result;
});
// 2.开启异步单元执行任务A
POOL_EXECUTOR.execute(futureTask);
// 3.执行任务B
String taskBResult = doSomethingB();
// 4.同步等待线程A运行结束
String taskAResult = futureTask.get();
// 5.打印两个任务执行结果
System.out.println(taskAResult + " " + taskBResult);
System.out.println(System.currentTimeMillis() - start);
}
下面代码与上面是等价的:
public static void main(String[] args) throws InterruptedException, ExecutionException {
long start = System.currentTimeMillis();
// 1.开启异步单元执行任务A
Future<String> futureTask =POOL_EXECUTOR.submit(() -> {
String result = null;
try {
result = doSomethingA();
} catch (Exception e) {
e.printStackTrace();
}
return result;
});
// 2.执行任务B
String taskBResult = doSomethingB();
// 3.同步等待线程A运行结束
String taskAResult = futureTask.get();
// 4.打印两个任务执行结果

本文详细介绍了FutureTask和CompletableFuture在Java异步编程中的应用,包括FutureTask的执行原理、使用实例,以及CompletableFuture的特性如通知等待、异步计算和结果转换,展示了如何利用它们进行任务调度和结果获取的灵活性。
542

被折叠的 条评论
为什么被折叠?



