本文纯属个人理解,如有正确,纯属巧合
线程池原理:提交任务后,如果发现当前“已经new的线程”小于corePool,即使有空闲的线程存在,也new个新的线程执行该任务。否则,将其加入BlockingQueue队列中,等待已有的线程“循环”去执行队列中的任务,如果此时队列也满了,则需要再次判断当前“已经new的线程”是否小于maximumPoolSize,如果小于,则新建线程;否则,根据拒绝策略进行处理。框架更倾向使用队列,因为创建新线程需要获取全局锁。
executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
AbortPolicy:直接抛出异常。
CallerRunsPolicy:只用调用者所在线程来运行任务,比如main线程。
DiscardOldestPolicy:丢弃队列里最近的一个任务,并执行当前任务。
DiscardPolicy:不处理,丢弃掉。
prestartAllCoreThreads():线程池提前创建并启动所有基本线程
ArrayBlockingQueue(int capacity):是一个基于数组结构的【有界】阻塞队列,此队列FIFO原则对元素进行排序
//keepAliveTime这个时间是maximumPoolSize-corePoolSize以外的空闲线程存活时间!!
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
LinkedBlockingQueue:一个基于链表结构的阻塞队列,此队列按FIFO排序元素,吞吐量通常高于ArrayBlocingQueue.静态工厂Executors.newFixedThreadPool()使用这个队列。
//corePoolSize==maximumPoolSize;keepAliveTime=0
//最大线程数=nThreads+linkedblockingqueu.size
//无界队列。先创建nThreads个线程,其他未执行的线程放到队列中
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
//corePoolSize==maximumPoolSize==1
//单线程执行,保证线程的顺序执行
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>(),
threadFactory));
}
SynchronousQueue:一个【不存储元素的阻塞队列】。每个插入操作必须等到另一个线程调用移除操作,否则插入操作一直处于阻塞状态,吞吐量通常高于Linkedblockingqueue,静态工厂方法Executors.newCachedThreadPool()使用这个队列。
注意:在使用SynchronousQueue通常要求maximumPoolSize是无界的,这样就可以避免上述情况发生(如果希望限制就直接使用有界队列)。对于使用SynchronousQueue的作用jdk中写的很清楚:此策略可以避免在处理可能具有内部依赖性的请求集时出现锁。
什么意思?如果你的任务A1,A2有内部关联,A1需要先运行,那么先提交A1,再提交A2,当使用SynchronousQueue我们可以保证,A1必定先被执行,在A1么有被执行前,A2不可能添加入queue中。
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
创建ForkJoin框架中用到的ForkJoinPool线程池,一个拥有多个任务队列(以便减少连接数),它默认使用当前机器可用的CPU个数作为并行数。
/**
* Creates a work-stealing thread pool using all
* {@link Runtime#availableProcessors available processors}
* as its target parallelism level.
* @return the newly created thread pool
* @see #newWorkStealingPool(int)
* @since 1.8
*/
public static ExecutorService newWorkStealingPool() {
return new ForkJoinPool
(Runtime.getRuntime().availableProcessors(),
ForkJoinPool.defaultForkJoinWorkerThreadFactory,
null, true);
}
PriorityBlockingQueue:一个具有优先级的【无限】阻塞队列。
shutdown():用于关闭启动线程,如果不调用该语句,jvm不会关闭。
awaitTermination():用于等待子线程结束,再继续执行下面的代码。该例中我设置一直等着子线程结束。先shutdown,再awaitTermination()
参考:Java线程池使用说明
参考:awaitTermination() shutdown()
参考:《Java并发编程的艺术》