线程池流程图:
线程池原理分析:
部分源码解读:
public class ThreadPoolExecutor extends AbstractExecutorService { /** * Creates a new {@code ThreadPoolExecutor} with the given initial * parameters and default thread factory and rejected execution handler. * It may be more convenient to use one of the {@link Executors} factory * methods instead of this general purpose constructor. * * @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. * @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} is null */ public ThreadPoolExecutor(int corePoolSize, // 核心线程数,实际运行线程 int maximumPoolSize, // 线程池最大线程数(最多可以创建的线程数) long keepAliveTime, // 空闲线程的存活时间 TimeUnit unit, // 超时秒数 BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); } }
线程池原理分析:重复利用机制,BlockingQueue阻塞式队列存放线程。
Executors对ThreadPoolExecutor核心构造函数进行封装。
ConcurrentLinkedDeque:
不阻塞,无界;
是一个适用于高并发场景下的队列,通过无锁的方式,实现了高并发状态下的高性能,通常ConcurrentLinkedQueue性能好于BlockingQueue.它是一个基于链接节点的无界线程安全队列。该队列的元素遵循先进先出的原则。头是最先加入的,尾是最近加入的,该队列不允许null元素。
ConcurrentLinkedQueue重要方法:
add 和offer() 都是加入元素的方法(在ConcurrentLinkedQueue中这俩个方法没有任何区别)
poll() 和peek() 都是取头元素节点,区别在于前者会删除元素,后者不会。
BlockingQueue:
可阻塞,有界;
阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作是:
在队列为空时,获取元素的线程会等待队列变为非空;
当队列满时,存储元素的线程会等待队列可用。
阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。
合理配置线程池:
CPU密集型时,任务配置尽可能少的线程数量,大概和CPU的核数相当,这样可以使得每个线程都在执行任务;IO密集型时,由于需要等待IO[I/O (硬盘/内存) 的读/写操作),如操作数据库、IO等待、阻塞、休眠]操作,线程并不是一直在执行任务,则配置尽可能多的线程(大部分线程都阻塞),故需要对配置线程数量:2*CPU核数。