关于ExecutorService和Future的中心思想

原创
2021/03/27 15:48
阅读数 217

最近发现关于ExecutorService的理解容易错误,会只是把它当成多线程的思想来理解,但这样的理解其实是不对的很片面的,所以简单讲讲我的个人理解。

private ExecutorService executorService=null;
if (executorService == null) {
            executorService = Executors.newCachedThreadPool();//这里创建一个线程池
}
//提交任务
Future<String> future = executorService.submit(new Callable<String>() {

                @Override
                public String call() throws Exception {
                    // TODO: 2021/3/27  
                    Thread.sleep(10000);
                    return "result";
                }
 });
 ......
 //阻塞获取结果
 String result=future.get();
 
 //任务集合调用
 List<Callable<String>> all = new ArrayList<>();
 ....添加任务
 List<Future<String>> fs = executorService.invokeAll(all);//这里要稍微注意下,这个是阻塞的,看源码就知道List<Future<String>>已经是所有任务完成后的结果集了,没有单个执行灵活。

使用很简单,我们可以看到,显示创建了一个线程池,然后提交任务返回一个任务凭证Future,当你需要用到结果的时候再去阻塞get()使用,所以整个的实现关键一个是线程池,一个是Future;线程池其实你自己new一个Thread也就有了,Future反而是关键。 所以这里的中心思想是【期货】, Future这里可以理解为未完成的货物或功能,也就是期货中的票剧(为什么piaoju是敏感词。。。),线程池就是期货公司。整个过程是这样的:

  1. 你去期货公司买期货,于是期货公司派了一个对接人(也就是线程)来跟你对接。
  2. 你说我要买一吨苹果,那期货公司肯定没有现成的,于是给你开了个单子(也就是Future)
  3. 期货公司有了货之后改变订单状态(这里不是订阅通知的模型,只是改变Future的状态,因为订阅通知需要你设置回调对象的,这样就没办法做到异步执行同步调用了)
  4. 或者你实在急用(主线程执行要快),那你直接就睡到期货公司等着(阻塞的get),取到货后一个订单就完成了。
  5. 当然你还可以同时买一吨苹果一吨梨一吨桔子,这样你就有了个三个单子,三个人给你办事(当然期货公司就一个人,也就是线程池只有一个线程)。
  6. 整个交易的时间就是三个人中办事最慢的那个的时间。

所以不要理解错因果关系,是因为要实现期货这个模型需要多线程,并不是有了多线程它就是期货。

展开阅读全文
加载中
点击引领话题📣 发布并加入讨论🔥
0 评论
0 收藏
0
分享
返回顶部
顶部