Java使用线程池的优势有哪些
池化技术相比大家已经屡见不鲜了,线程池、数据库连接池、Http连接池等等都是对这个思想的应用。池化技术的思想主要是为了减少每次获取资源的消耗,提高对资源的利用率。线程池提供了一种限制和管理资源(包括执行一个任务)。每个线程池还维护一些基本统计信息,例如已完成任务的数量。
这里借用《Java并发编程的艺术》提到的来说一下使用线程池的好处:
- 降低资源消耗。通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
- 提高响应速度。当任务到达时,任务可以不需要的等到线程创建就能立即执行。
- 提高线程的可管理性。线程是稀缺资源,如果无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,使用线程池可以进行统一的分配,调优和监控。
Executor框架
Executor框架是Java5之后引进的,在Java5之后,通过Executor来启动线程比使用Thread的start方法更好,除了更易管理,效率更好(用线程池实现,节约开销)外,还有关键的一点:有助于避免this逃逸问题。
补充:this逃逸是指在构造函数返回之前其他线程就持有该对象的引用.调用尚未构造完全的对象的方法可能引发令人疑惑的错误。
Executor框架不仅包括了线程池的管理,还提供了线程工厂、队列以及拒绝策略等,Executor框架让并发编程变得更加简单。
Executor框架结构(主要由三大部分组成)
- 任务(Runnable/Callable)执行任务需要实现的Runnable接口或Callable接口。Runnable接口或Callable接口实现类都可以被ThreadPoolExecutor或ScheduledThreadPoolExecutor执行。
- 任务的执行(Executor)如下图所示,包括任务执行机制的核心接口Executor,以及继承自Executor接口的ExecutorService接口。ThreadPoolExecutor和ScheduledThreadPoolExecutor这两个关键类实现了ExecutorService接口。
这里提了很多底层的类关系,但是,实际上我们需要更多关注的是ThreadPoolExecutor这个类,这个类在我们实际使用线程池的过程中,使用频率还是非常高的。
注意:通过查看ScheduledThreadPoolExecutor源代码我们发现ScheduledThreadPoolExecutor实际上是继承了ThreadPoolExecutor并实现了ScheduledExecutorService,而ScheduledExecutorService又实现了ExecutorService,正如我们下面给出的类关系图显示的一样。
ThreadPoolExecutor类描述:
//AbstractExecutorService实现了ExecutorService接口 publicclassThreadPoolExecutorextendsAbstractExecutorService
ScheduledThreadPoolExecutor类描述:
//ScheduledExecutorService实现了ExecutorService接口 publicclassScheduledThreadPoolExecutor extendsThreadPoolExecutor implementsScheduledExecutorService
3)异步计算的结果(Future)Future接口以及Future接口的实现类FutureTask类都可以代表异步计算的结果。
当我们把Runnable接口或Callable接口的实现类提交给ThreadPoolExecutor或ScheduledThreadPoolExecutor执行。(调用submit()方法时会返回一个FutureTask对象)
Executor框架的使用示意图
- 主线程首先要创建实现Runnable或者Callable接口的任务对象。
- 把创建完成的实现Runnable/Callable接口的对象直接交给ExecutorService执行:ExecutorService.execute(Runnablecommand))或者也可以把Runnable对象或Callable对象提交给ExecutorService执行(ExecutorService.submit(Runnabletask)或ExecutorService.submit(Callabletask))。
- 如果执行ExecutorService.submit(…),ExecutorService将返回一个实现Future接口的对象(我们刚刚也提到过了执行execute()方法和submit()方法的区别,submit()会返回一个FutureTask对象)。由于FutureTask实现了Runnable,我们也可以创建FutureTask,然后直接交给ExecutorService执行。
- 最后,主线程可以执行FutureTask.get()方法来等待任务执行完成。主线程也可以执行FutureTask.cancel(booleanmayInterruptIfRunning)来取消此任务的执行。
以上就是Java使用线程池的优势有哪些的详细内容,更多关于Java线程池的资料请关注毛票票其它相关文章!
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。