public class ThreadPool {
public static ExecutorService getPool(String poolName){
ThreadFactory namedThreadFactory = new ThreadFactoryBuilder().setNameFormat(poolName + “-%d”).build();
//Common Thread Pool
ExecutorService pool = new ThreadPoolExecutor(5, 100,
60000L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue(10), namedThreadFactory, new ThreadPoolExecutor.AbortPolicy());
return pool;
}
public static void main(String[] args) throws Exception{
ExecutorService pool = getPool("aa");
for (int i=0;i<2000;++i){
pool.submit(new Runnable() {
@SneakyThrows
@Override
public void run() {
Thread.sleep(10000000L);
}
});
}
pool.shutdown();
}
}
我建了一个核心线程为5,最大线程数为100,线程存活时间为60000单位是毫秒(这个线程后面会说到),一个长度为10的工作队列,线程工厂,线程策略为拒绝的策略。
1.当我们for循环第一次时,这时线程工厂会创建一个新的线程,这个线程为核心线程,
2.当第6次时也就是核心线程满了,这时会把任务放到工作队列,当工作队列也满了,这时线程工厂会创建新的线程,新线程执行的任务是新加的任务并不是从工作队列取的,当最大线程也满了,再进来任务则执行我们传入的拒绝策略,抛出异常。
3.当线程达最大线程之间时,如果没有任务进来,且任务队列有任务,当线程执行完任务会去任务队列取任务执行,当任务执行完且没有新任务进来,线程会根据配置的时间慢慢降低到核心线程数(线程存活时间就是针对这类核心线程到最大线程之间的这些普通线程的)
4.如果线程降到核心线程数和最大线程数之间,如果新进来任务,如果线程空闲着(设置了60000ms,线程并不会立即销毁)那么线程直接执行新进来的任务,如果没有空闲的则任务加入队列,队列满了再创建线程执行新进的任务。
总结:
1.任务进来先创建核心线程,核心线程满了放入队列
2.队列满了创建普通线程
3.线程满了并且队列满了执行reject策略
4.无任务时普通线程会根据超时时间慢慢降到核心线程数,此过程中如果有任务进来,空闲线程去执行任务,线程都不空闲放入队列,重复步骤2
5.所有任务执行完,线程数降到核心线程数
ps:核心线程并不是指某几个特定线程,只是一个概念。