线程池的一些理解记录
几种线程池的类型
1.可缓存的线程池
ExecutorService executorService = Executors.newCachedThreadPool();
public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
60L, TimeUnit.SECONDS,
new SynchronousQueue<Runnable>());
}
这个线程池的特点是没有核心线程为0,最大线程数是很多的 然后任务队列的容量为零,这就代表着
每次有任务进来都会创建一个线程去运行任务。这种线程池是很浪费资源的。
2.单线程的线程池
public static ExecutorService newSingleThreadExecutor() {
return new FinalizableDelegatedExecutorService
(new ThreadPoolExecutor(1, 1,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>()));
}
这个线程池的特点顾名思义就是一个单线程的,核心线程数为1,最大线程数也是1 任务队列是一个线程安全的链表可以无限的丢入任务然后慢慢的去进行消费,其实线程池就是一个生产者消费者模式。
3.可定长的线程池
public static ExecutorService newFixedThreadPool(int nThreads) {
return new ThreadPoolExecutor(nThreads, nThreads,
0L, TimeUnit.MILLISECONDS,
new LinkedBlockingQueue<Runnable>());
}
这个线程池的特点就是核心线程数和最大核心线程数是一样的 然后只要核心线程池用完了就会直接丢进我们的阻塞队列去进行慢慢的消费。
还有可以自定义的ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize // 核心线程数,
int maximumPoolSize // 最大线程数,
long keepAliveTime // 空闲时间,
TimeUnit unit // 时间单位,
BlockingQueue<Runnable> workQueue // 任务队列) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
这个我们可以根据自己的服务器进行配置合理的线程数和一些非核心线程释放还有任务队列以及一些线程工厂和拒绝策略。
线程池的任务的提交以及任务的执行
1.如果线程数小于核心线程数那么会直接会起一个线程来执行当前任务。
2.如果是大于核心线数大于核心线程数的话会把任务丢进任务队列,等待运行中的线程执行完。
3.如果我们的任务队列满了的话,并且小于最大线程数这时会创建一个临时的线程来执行当前的任务。
4.如果线程数达到了最大线程数而且任务队列也存满的话就会执行相对应的拒绝策略。
这四个步骤是线程池的大概执行步骤。
拒绝策略
1.ThreadPoolExecutor.AbortPolicy 默认执行的决绝策略,拒绝任务并抛出异常。
2.ThreadPoolExecutor.DiscardPolicy 直接拒绝任务,不抛出错误
3.ThreadPoolExecutor.DiscardOldestPolicy 触发拒绝策略,只要还有任务新增,一直会丢弃阻塞队列的最老的任务,并将新的任务加入
4.ThreadPoolExecutor.CallerRunsPolicy 使用调用线程直接运行任务
总结
以上是我对线程池的一些简单理解后续会深入源码去研究,上面所述如有错误欢迎交流哦