文章目录
1. ThreadPoolExecutor参数
- 当
taskCount > MaximumPoolSize
的时候,才会active
升级为MaximumPoolSize
; - 当超过
QueueSize
的时候,则会执行RejectedExecutionHandler
; - 若升级到
MaximumPoolSize
的线程,若线程空闲的时间超过KeepAliveTime
,则会被回收。线程池中的数量重新回归到active
的线程数。 getQueue()
:通过ThreadPoolExecutor可以获取到任务队列,因此可以直接修改任务队列;但是,直接添加任务到队列中,不会生效;因为线程池中没有线程可用,因此,需要使用execute先执行其它的任务,让线程池中存在工作线程才能执行添加到queue中的任务。
public class ThreadPoolExecutorDemo {
public static void main(String[] args) {
ThreadPoolExecutor executor = buildThreadPool();
int activeSize = -1;
for (; ; ) {
int activeCount = executor.getActiveCount();
int queueSizeFromExecutor = executor.getQueue().size();
if (activeCount != activeSize) {
System.out.println("Active: " + activeCount);
System.out.println("QueueSize: " + queueSizeFromExecutor);
System.out.println("MaximumPoolSize: " + executor.getMaximumPoolSize());
System.out.println("TaskCount: " + executor.getTaskCount());
System.out.println("=========================");
activeSize = activeCount;
}
}
}
private static ThreadPoolExecutor buildThreadPool() {
ThreadPoolExecutor executorService = new ThreadPoolExecutor(1, 2, 30, TimeUnit.SECONDS,
new ArrayBlockingQueue<>(1), r -> {
Thread thread = new Thread(r);
return thread;
}, new ThreadPoolExecutor.AbortPolicy());
System.out.println("=== build thread pool successful! ====");
executorService.execute(() -> ThreadPoolExecutorDemo.sleepSecond(100));
executorService.execute(() -> ThreadPoolExecutorDemo.sleepSecond(10));
executorService.execute(() -> ThreadPoolExecutorDemo.sleepSecond(100));
return executorService;
}
private static void sleepSecond(long sec) {
try {
System.out.println(Thread.currentThread().getName() + " sleep!");
TimeUnit.SECONDS.sleep(sec);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
2. newCachedThreadPool
- 构造函数解析:
- corePoolSize:核心线程大小默认是0;
- MaximumPoolSize:最大是Integer.MAX_VALUE;
- Queue:使用的是SynchronousQueue,这种Queue只能存放一个元素;所以,提交一个任务时,就会创建一个线程出来;
- KeepAliveTime:默认是60s;且CorePoolSize的大小为0;因此,当超过KeepAliveTime时,且任务都执行完成时,会释放所有的线程,导致线程池的关闭。
- 特性:因为都是直接开辟出新的线程给任务执行,因此,只适用于
短小
的任务;若是用于长任务的场景,会出现开辟大量的线程,直至栈溢出。
3. newFixedThreadPool
- 构造函数解析:
- corePoolSize和MaximumPoolSize是一致的。
- Queue:使用的是LinkedBlockingQueue作为任务的暂存list;默认可以存放的大小为Integer.MAX_VALUE;只有超过这个大小的时候,才会执行拒绝策略。
- KeepAliveTime:默认是0s;但是因为corePoolSize和MaximumPoolSize是一致的,没有可以被回收的线程,所以,此选项无意义。
4. newSingleThreadPool
-
构造函数解析:
- corePoolSize和MaximumPoolSize是一致的,都是1;
- Queue:使用的是LinkedBlockingQueue作为任务的暂存list;默认可以存放的大小为Integer.MAX_VALUE;只有超过这个大小的时候,才会执行拒绝策略。
- KeepAliveTime:默认是0s;但是因为corePoolSize和MaximumPoolSize是一致的,没有可以被回收的线程,所以,此选项无意义。
- 因此可以等价于
newFixedThreadPool(1)
;
-
newSingleThreadPool和Thread的区别:
- newSingleThreadPool可以一直存活,而Thread执行完任务则被销毁。
- newSingleThreadPool可以缓存任务,可以不断一个个的执行任务;而Thread无法缓存任务。只能执行一个任务。
5. newWorkStealingPool(since jdk1.8)
- 构造函数解析:
- 返回的是ForkJoinPool;而不是其它Executor的ThreadPool;
- CorePoolSize:为当前系统主机的CPU核数;
- 当执行完任务的时候,会自动销毁线程池;