文章插图
- 之前我们介绍了线程池的四种拒绝策略,了解了线程池参数的含义,那么今天我们来聊聊
Java
中常见的几种线程池,以及在jdk7
加入的ForkJoin
新型线程池
- 首先我们列出
Java
中的六种线程池如下
- 在了解集中线程池时我们先来熟悉一下主要几个类的关系,
ThreadPoolExecutor
的类图,以及Executors
的主要方法:
文章插图
文章插图
- 上面看到的类图,方便帮助下面的理解和查看,我们可以看到一个核心类
ExecutorService
, 这是我们线程池都实现的基类,我们接下来说的都是它的实现类 。
FixedThreadPool
线程池的特点是它的核心线程数和最大线程数一样,我们可以看它的实现代码在Executors#newFixedThreadPool(int)
中,如下:
public static ExecutorService newFixedThreadPool(int nThreads) {return new ThreadPoolExecutor(nThreads, nThreads,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>());}
我们可以看到方法内创建线程调用的实际是ThreadPoolExecutor
类,这是线程池的核心执行器,传入的nThread
参数作为核心线程数和最大线程数传入,队列采用了一个链表结构的有界队列 。
- 这种线程池我们可以看作是固定线程数的线程池,它只有在开始初始化的时候线程数会从0开始创建,但是创建好后就不再销毁,而是全部作为常驻线程池,这里如果对线程池参数不理解的可以看之前文章 《解释线程池各个参数的含义》 。
- 对于这种线程池他的第三个和第四个参数是没意义,它们是空闲线程存活时间,这里都是常驻不存在销毁,当线程处理不了时会加入到阻塞队列,这是一个链表结构的有界阻塞队列,最大长度是Integer. MAX_VALUE
SingleThreadExecutor
线程的特点是它的核心线程数和最大线程数均为1,我们也可以将其任务是一个单例线程池,它的实现代码是Executors#newSingleThreadExcutor()
, 如下:
public static ExecutorService newSingleThreadExecutor() {return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>()));}public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {return new FinalizableDelegatedExecutorService(new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(),threadFactory));}
- 上述代码中我们发现它有一个重载函数,传入了一个
ThreadFactory
的参数,一般在我们开发中会传入我们自定义的线程创建工厂,如果不传入则会调用默认的线程工厂 - 我们可以看到它与
FixedThreadPool
线程池的区别仅仅是核心线程数和最大线程数改为了1,也就是说不管任务多少,它只会有唯一的一个线程去执行 - 如果在执行过程中发生异常等导致线程销毁,线程池也会重新创建一个线程来执行后续的任务
- 这种线程池非常适合所有任务都需要按被提交的顺序来执行的场景,是个单线程的串行 。
cachedThreadPool
线程池的特点是它的常驻核心线程数为0,正如其名字一样,它所有的县城都是临时的创建,关于它的实现在Executors#newCachedThreadPool()
中,代码如下:
public static ExecutorService newCachedThreadPool() {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>());}public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {return new ThreadPoolExecutor(0, Integer.MAX_VALUE,60L, TimeUnit.SECONDS,new SynchronousQueue<Runnable>(),threadFactory);}
- 从上述代码中我们可以看到
CachedThreadPool
线程池中,最大线程数为
推荐阅读
- python之最详细字符串篇
- 什么鱼凶猛 观赏鱼中最凶猛的鱼是哪种
- Spring Boot中一接多口实现
- 如何挑选三文鱼
- 如何挑选薄荷
- 如何挑选鲅鱼
- 北方茶市的重要参照,走进中国近海第茶―御海湾
- 生活中常见事物蕴含的道理 生活中的事物
- 烟雨江湖主线任务攻略 烟雨江湖中的支线任务攻略大全
- 龙井茶用中投法泡吗,想喝好的龙井茶