前面的例子中总是需要线程时就创建,不需要就销毁它。但频繁创建和销毁线程是很耗资源的,在并发量较高的情况下频繁创建和销毁线程会降低系统的效率。线程池可以通过重复利用已创建的线程降低线程创建和销毁造成的消耗。
参考JDK1.8中的相关类,画出下图。
(此图不是十分准确,有些类实现了两个接口,这里只展示出了一个)
本章只是简单地介绍下它们,在以后的文章中会选一些最重要的来学习。
Executor
此接口提供一种将任务提交与每个任务将如何运行的机制分离开来的方法。它只提供了execute(Runnable)这么一个方法,用于执行已提交的Runnable任务。
ExecutorService
继承了Executor接口,用于提交一个用于执行的Runnable任务、试图停止所有正在执行的活动任务,暂停处理正在等待的任务、执行给定的任务。
AbstractExecutorService
提供了ExecutorService的默认实现。
ThreadPoolExecutor
提供一个可扩展的线程池实现,是最出名的“线程池”。
ForkJoinPool
JDK1.7中新增的一个线程池,与ThreadPoolExecutor一样,同样继承了AbstractExecutorService。ForkJoinPool是Fork/Join框架的两大核心类之一。与其它类型的ExecutorService相比,其主要的不同在于采用了工作窃取算法(work-stealing):所有池中线程会尝试找到并执行已被提交到池中的或由其他线程创建的任务。这样很少有线程会处于空闲状态,非常高效。这使得能够有效地处理以下情景:大多数由任务产生大量子任务的情况;从外部客户端大量提交小任务到池中的情况。
ScheduledExecutorService&ScheduledThreadPoolExecutor
ScheduledExecutorService继承了ExecutorService,可安排在给定的延迟后运行或定期执行命令。
ScheduledThreadPoolExecutor继承了ThreadPoolExecutor,实现了ScheduledExecutorService。
CompletionService&ExecutorCompletionService
CompletionService接口是将生产新的异步任务与使用已完成任务的结果分离开来的服务。生产者利用submit()提交要执行的任务。使用者利用take()获取并移除已完成的任务的返回值,并按照完成这些任务的顺序处理它们的结果。
通常,CompletionService 依赖于一个单独的 Executor 来实际执行任务,在这种情况下,CompletionService 只管理一个内部完成队列。ExecutorCompletionService 类提供了此方法的一个实现。此类将那些完成时提交的任务放置在可使用take()访问的队列上。
Callable&Future
Callable接口类似于Runnable,两者作用都是定义任务。不同的是,被线程执行后,Callable可以返回结果或抛出异常。而Runnable不可以。Callable的返回值可以通过Future来获取。
未完待续。。。
本文就先讲到这里,想了解Java并发编程更多内容请参考: