CompletableFuture
- Future接口(FutureTask实现类)定义了操作异步任务执行一些方法,如获取异步任务的执行结果、取消任务的执行、判断任务是否被取消、判断任务执行是否完毕等。
- 如主线程让一个子线程去执行任务,子线程可能比较耗时,启动子线程开始执行任务后,主线程就去做其他事情了,忙其他事情或者先执行完,过了一会儿才去获取子任务的执行结果或变更的任务状态
- Future是java5的一个接口,它提供了一种异步并行计算的功能
- 如果主线程需要执行一个很耗时的计算任务,我们就可以通过future把这个任务放到异步线程中执行
- 主线程继续处理其他任务或先行结束,再通过Future获取计算结果
- 三个特点(多线程、有返回、异步任务)
- Future优点:future+线程池异步多线程任务配合,能显著提高程序的执行效率
public class FutureThreadPoolDemo {
public static void main(String[] args) throws InterruptedException, ExecutionException {
FutureThreadPoolDemo futureThreadPoolDemo = new FutureThreadPoolDemo();
futureThreadPoolDemo.m1();//1114毫秒
futureThreadPoolDemo.m2();//540毫秒
}
public void m1() throws InterruptedException {
//3个任务,目前只有一个线程来处理、
long startTime = System.currentTimeMillis();
Thread.sleep(500);
Thread.sleep(300);
Thread.sleep(300);
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
}
public void m2() throws ExecutionException, InterruptedException {
//3个任务,目前开启多个异步任务线程
long startTime = System.currentTimeMillis();
ExecutorService threadPool = Executors.newFixedThreadPool(3);
FutureTask<String> futureTask1 = new FutureTask<>(()->{
Thread.sleep(500);
return "";
});
FutureTask<String> futureTask2 = new FutureTask<>(()->{
Thread.sleep(300);
return "";
});
FutureTask<String> futureTask3 = new FutureTask<>(()->{
Thread.sleep(300);
return "";
});
threadPool.submit(futureTask1);
threadPool.submit(futureTask2);
threadPool.submit(futureTask3);
//获取返回结果,
System.out.println(futureTask1.get());
System.out.println(futureTask2.get());
System.out.println(futureTask3.get());
threadPool.shutdown();
long endTime = System.currentTimeMillis();
System.out.println(endTime - startTime);
}
}
- Future缺点:get方法容易引起阻塞
public class FutureAPIDemo {
public static void main(String[] args) throws ExecutionException, InterruptedException {
FutureTask<String> futureTask = new FutureTask<>(()->{
System.out.println("begin");
Thread.sleep(5000);
return "end";
});
Thread t1 = new Thread(futureTask, "t1");
t1.start();
//获取线程返回值,如果futureTask.get()方法没有放在最后,则会导致阻塞,当5秒后线程执行结束由返回值时才会继续执行
System.out.println(futureTask.get());
System.out.println("主线程执行其他任务");
}
}
- 使用过时抛出异常(多个线程可能会抛出多个异常)
System.out.println(futureTask.get(3, TimeUnit.SECONDS));
- 使用循环判断是否执行完成(需要不停的轮询,会耗费cpu资源,而且也不见得及时得得到计算结果)
while (true){
//每隔0.5秒判断是否完成
if (futureTask.isDone()){
System.out.println(futureTask.get());
break;
}else {
Thread.sleep(500);
}
}
结论:Future对于结果的获取不是很友好,只能通过阻塞或轮询的方式得到任务的结果
标签:Thread,System,JUC2,FutureTask,线程,println,out From: https://www.cnblogs.com/blackyoumo/p/16977098.html