请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

没太看明白FutureTask的方便和线程数

老师,可能是看久了,头有点懵

Future类中,

 ExecutorService executorService = Executors.newCachedThreadPool();

        Future<String> future = executorService.submit(new MyCallable());

        log.info("do something in main");

        Thread.sleep(1000);

        String result = future.get();

        log.info("result:{}", result);

实例化一个线程池,开启一个线程,去接收MyCallable中的结果,然后future.get获得结果,

再看futureTask类

        new Thread(futureTask).start();

        log.info("do something in main");

        Thread.sleep(1000);

        String result = futureTask.get();

        log.info("result:{}", result);

futureTask也是开了个线程接收返回结果,直观来看,菜鸟基本都会觉得第一种写法,少了个线程启动start,反而要方便些,作用跟第二种也差不多。

问题:

  1. 这两种方式,分别是开了几个线程,我有点不太理解,该怎么算线程。

  2. 既然Task是单独开启一个线程,来存放所监督的线程返回结果,第一个future中,直接在线程池多拿个线程出来,效果不是一样的?

    (这问,也是由于没太明白这两个例子中线程数该怎么算,我觉得把线程数说出来,比如我理解的是,第一个例子,开启一个线程,做了两件事,第二个例子,开启两个线程,分别做了某一件事,理解起来更方便,当然我这理解可能是错的)

正在回答

1回答

你好,其实关于FutureTask,你问的那两个问题不是关键,我来具体说一下。

先说Future。Executor是Runnable和Callable的调度容器,Future是对于具体的Runnable或者Callable任务的执行结果进行取消、查询是否完成、获取结果、设置结果操作。其实很好用。

而FutureTask呢,是一个RunnableFuture< V>,而RunnableFuture实现了Runnbale又实现了Futrue< V>这两个接口,他还可以包装Runnable和Callable< V>,看他的构造函数,可以知道Runnable注入会被Executors.callable()函数转换为Callable类型,即FutureTask最终都是执行Callable类型的任务,具体可以看callable()方法和 RunnableAdapter适配器。由于FutureTask实现了Runnable,因此它既可以通过Thread包装来直接执行,也可以提交给ExecuteService来执行。并且还可以直接通过get()函数获取执行结果,该函数会阻塞,直到结果返回。因此FutureTask既是Future、Runnable,又是包装了Callable(如果是Runnable最终也会被转换为Callable ), 它是这两者的合体。

课程里的例子不是为了表达相比Future的写法好在哪里,而是给出另外的用法。可以根据实际需要选择不同的写法。Future、Runnable、Callable支持的,FutureTask都能满足。

看看现在是否明白啦~



3 回复 有任何疑惑可以回复我~
  • 提问者 Echo鑫 #1
    非常感谢!
    回复 有任何疑惑可以回复我~ 2018-03-24 09:14:14
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信