Java多线程之Executor框架和手写简易的线程池(5)

FutureTask是对Future的基本实现,具有启动和取消计算的方法,查询计算是否完整,并检索计算结果。FutureTask对Future做了一定得扩展:
void run() //将此future设置为其计算结果,除非已被取消。 
protected boolean runAndReset()  //执行计算而不设置其结果,然后重置为初始状态,如果计算遇到异常或被取消,则不执行此操作。 
protected void set(V v) //将此Future的结果设置为给定值,除非Future已被设置或已被取消。 
protected void setException(Throwable t) //除非已经设置了此 Future 或已将其取消,否则它将报告一个 ExecutionException,并将给定的 throwable 作为其原因。 

FutureTask除了实现Future接口外,还实现了Runnable接口。所以FutureTask可以由Executor执行,也可以由调用线程直接执行futureTask.run()。

当FutureTask处于未启动或已启动状态时,执行FutureTask.get()方法将导致调用线程阻塞;

当FutureTask处于已完成状态时,执行FutureTask.get()方法将导致调用线程立即返回结果或抛出异常。

当FutureTask处于未启动状态时,执行FutureTask.cancel()方法将导致此任务永远不会被执行;

当FutureTask处于已启动状态时,执行FutureTask.cancel(true)方法将以中断执行此任务线程的方式来尝试停止该任务;

当FutureTask处于已启动状态时,执行FutureTask.cancel(false)方法将不会对正在执行此任务的线程产生影响(让正在执行的任务运行完成)。

关于是否使用Executors

在之前阿里巴巴出的java开发手册中,有明确提出禁止使用Executors:


【强制】线程池不允许使用 Executors 去创建,而是通过 ThreadPoolExecutor 的方式,
 这样的处理方式让写的同学更加明确线程池的运行规则,规避资源耗尽的风险。

在上面我们分析过使用Executors创建的几种线程池的使用场景和缺点,大多数情况下出问题在于可能导致OOM,在我实际使用中基本没有遇到过这样的情况。但是考虑到阿里巴巴这样体量的并发请求,可能遇到这种情况的几率较大。所以我们还是应该根据实际情况考虑是否使用,当然实际遵循阿里巴巴开发手册来可能会更好一点,毕竟这是国类顶尖公司常年在生产中积累下的经验。

最后,在本节中只是简单介绍线程池及其基本原理,帮助更好的理解线程池。并不涉及具体如何使用。

Linux公社的RSS地址https://www.linuxidc.com/rssFeed.aspx

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/5a88e4496d8fb0a25cdc5c39ccb4ec72.html