3.7 线程池
线程池指的是可重复利用的线程集合,线程池的作用即可以同时执行多个任务并且线程可以重复使用,增加多任务处理效率。
3.7.1 ThreadPoolExecutor创建线程池
阿里开发规范不要显示创建线程池,也不要用excutors静态方法创建线程池,而是用ThreadPoolExecutor。
使用示例:
static ThreadFactory myThreadFactory = new
ThreadFactory() {
@Override
public Thread newThread(Runnable runnable) {
return new Thread(runnable);
}
};
public static ExecutorService pool = new ThreadPoolExecutor(1, 12,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(1024), myThreadFactory, new ThreadPoolExecutor.AbortPolicy());
ThreadPoolExecutor构造方法中各个参数的含义:
corePoolSize:线程池拥有的线程数量,不管空闲不空闲一直都在的。
maximumPoolSize: 线程池中允许的最大线程数量。
keepAliveTime:当线程池中线程 最大的闲置时间,到了限制时间会销毁非核心线程。
unit:闲置时间单位,秒,分,时。
workQueue:任务无法获得线程进行处理时进入该队列等待。
threadFactory:线程工厂,具体的创建线程的方法,开放创建线程时操作。
handler:当任务无法提交,等待队列也满时,对任务的处理方法。
源码注释:
/**
* Creates a new {@code ThreadPoolExecutor} with the given initial
* parameters.
* @param corePoolSize the number of threads to keep in the pool, even
* if they are idle, unless {@code allowCoreThreadTimeOut} is set
* @param maximumPoolSize the maximum number of threads to allow in the
* pool
* @param keepAliveTime when the number of threads is greater than
* the core, this is the maximum time that excess idle threads
* will wait for new tasks before terminating.
* @param unit the time unit for the {@code keepAliveTime} argument
* @param workQueue the queue to use for holding tasks before they are
* executed. This queue will hold only the {@code Runnable}
* tasks submitted by the {@code execute} method.
* @param threadFactory the factory to use when the executor
* creates a new thread
* @param handler the handler to use when execution is blocked
* because the thread bounds and queue capacities are reached
* @throws IllegalArgumentException if one of the following holds:<br>
* {@code corePoolSize < 0}<br>
* {@code keepAliveTime < 0}<br>
* {@code maximumPoolSize <= 0}<br>
* {@code maximumPoolSize < corePoolSize}
* @throws NullPointerException if {@code workQueue}
* or {@code threadFactory} or {@code handler} is null
*/
注意阿里开发规范在线程池的相关规范不一定就是最好的,重要的看实际情况,直接使用Excutors里有些相关操作也是极好的。
3.7.2 Executors创建线程池
使用方式,Executors还提供了很多其他类型的线程池,此处只提下newFixedThreadPool这种方式。使用Executors本质上还是通过ThreadPoolExecutor创建的线程池,不过ThreadPoolExecutor的构造参数做了限制。
ExecutorService threadPool = Executors.newFixedThreadPool(5);
newFixedThreadPool()创建方式源码:
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}