原博客链接:Thread / Runnable / Callable / Future /FutureTask (notion.site)
完善过程
- JDK1.0 最开始使用多线程的时候,开启一个线程两种方式,继承
Thread
实现Runnable
接口属三无产品,无法传入参数、无发接收返回值、无法捕捉异常; - JDK1.5 出实现了
Callable
接口,有返回值、可以入参、可以捕捉异常。还可以通过FutureTask
封装异步任务,便捷获取结果。 - JDK1.5 就可以使用
ExecutorService ****
与Callable
和Future
来实现获取线程池中的计算结果(但是Future.get的时候是阻塞的) - JDK1.8 出现
CompletionService
通过异步的LinkedBlockQueue
无界队列生产者消费者模型,来实现线程计算与获取结果的解耦,在take的保证在队列中拿到最先完成的任务。(不在此展开) - JDK1.8 出现
CompletableFurute
借鉴了Google的guava
,异步回调链式编排,让Java拥有了完整的非阻塞编程模型:Future、Promise 和 Callback(在Java8之前,只有无Callback 的Future)(不在此展开)
Callable
-
java中开启多线程的根源还是在Thread类中, 在Thread源码中跟Callable是没有联系的,因为Thread类的构造方法只有Runnable 根本没有Callable,但是Callable又想实现多线程的功能 那么要找同时满足实现Runnable接口,并且接受Callable接口的实现 ,
FutureTask
。 -
其中FutureTask实现了RunnableFuture接口, RunnableFuture接口又实现了Future与Runnable接口。 并且FutureTask的构造方法可以接收Callable接口实例,所以它可以被传入Thread类中来实现多线程的启动,利用Future接口中的get()方法接受结果。
-
所以说实现
callable
接口后,都可以传入FutureTask
中,再将其传入到thread
类中或者提交到excetorService
中,供后续使用特性。
FutureTask 与 Future
Future
接口的五个方法
-
FautureTask 作为 Future的基础实现,提供了对于Callable获取结果等特性更加便捷的操作 FutureTask可以封装异步任务,然后提交给Thread或ExecutorService执行,然后获取任务执行结果。
-
虽然FutureTask继承的是Runnable,但是通过自己的拓展也可以返回结果。
-
FutureTask虽然继承的是Runnable,没有继承与Callable接口,但是通过自己的拓展也可以返回结果 通过FutureTask继承结构可知,因为他实现于Runnable接口,所以它也可以提交到ExecutorService被管理,也可以传入Thread的构造器。
-
FutureTask两种方式 FutureTask + Thread 与 FutureTask + ExecutorService
//既可以通过线程池来执行FutureTask提交的任务 FutureTask<String> futureTask = new FutureTask<>(()->{ System.out.println("正在执行任务"); System.out.println(Thread.currentThread().getName()); try { Thread.sleep(5000); } catch (InterruptedException e) { e.printStackTrace(); } }, "我是返回值"); //这是一个Runnable类型的任务 ExecutorService exector = Executors.newFixedThreadPool(3); exector.submit(futureTask); //也可以通过新建一个线程来执行FutureTask提交的任务 FutureTask task = new FutureTask(new Callable() { @Override public Object call() throws Exception { System.out.println(Thread.currentThread().getName() + "========>正在执行!"); return "SUCCESS"; } }); new Thread(task).start();
Reference
- CompletionService和ExecutorCompletionService详解 - 简书 (jianshu.com)
- “既生 ExecutorService, 何生 CompletionService?” - 知乎 (zhihu.com)
- 4.12、CompletionService:如何批量执行异步任务? - 知乎 (zhihu.com)
- 并发编程 | CompletionService - 如何优雅地处理批量异步任务-腾讯云开发者社区-腾讯云 (tencent.com)
- 浅谈Java多线程之FutureTask - 剽悍一小兔 - 博客园 (cnblogs.com)
- Java并发编程(六)——Callable接口 - 路半_知风 - 博客园 (cnblogs.com)
- 可取消的异步任务——FutureTask用法及解析 - 简书 (jianshu.com)