Java 线程池

解释说明:

Executor 是线程池最顶层的接口,在 Executor 中只有一个 execute 方法,用于执行任务。至于线程的创建、调度等细节由子类实现。

ExecutorService 继承并拓展了 Executor,在 ExecutorService 内部提供了更全面的任务提交机制以及线程池关闭方法。

ThreadPoolExecutor 是 ExecutorService 的默认实现,所谓的线程池机制也大多封装在此类当中。

ScheduledExecutorService 继承自 ExecutorService,增加了定时任务相关方法。

ScheduledThreadPoolExecutor 继承ThreadPoolExecutor,并实现了 ScheduledExecutorService 接口。

ForkJoinPool 是一种支持任务分解的线程池,一般要配合可分解任务接口 ForkJoinTask 来使用。

 

创建线程池

为了方便开发者可以更方便的使用线程池,JDK 中给我们提供了一个线程池的工厂类—Executors。在 Executors 中定义了多个静态方法,用来创建不同配置的线程池。常见有以下几种。(阿里Java开发手册 中已经严禁使用 Executors 来创建线程池)

1. newSingleThreadExecutor:创建一个单线程化的线程池,它只会用唯一的工作线程来执行任务,保证所有任务按先进先出的顺序执行。

2. newCachedThreadPool 创建一个可缓存线程池,如果线程池长度超过处理需要,可灵活回收空闲线程,若无可回收,则新建线程

3. newFixedThreadPool 创建一个固定数目的、可重用的线程池

4. newScheduledThreadPool创建一个定时线程池,支持定时及周期性任务执行

为何禁止使用 Executors

因为会造成不可预料的后果,尤其是 newFixedThreadPool 和 newCachedThreadPool 这两个方法。newFixedThreadPool传入的是一个无界的阻塞队列,理论上可以无限添加任务到线程池。当核心线程执行时间很长(比如 sleep10s),则新提交的任务还在不断地插入到阻塞队列中,最终造成OOM。newCachedThreadPool缓存线程池的最大线程数为 Integer 最大值。当核心线程耗时很久,线程池会尝试创建新的线程来执行提交的任务,当内存不足时就会报无法创建线程的错误。

 

线程池工作原理分析

在线程池内部主要包含以下几个部分:

worker 集合:保存所有的核心线程和非核心线程,其本质是一个HashSet

等待任务队列:当核心线程的个数达到 corePoolSize 时,新提交的任务会被先保存在等待队列中,其本质是一个阻塞队列 BlockingQueue

ctl:是一个 AtomicInteger 类型,二进制高 3 位用来标识线程池的状态,低 29 位用来记录池中线程的数量

处理流程

1. 当前线程池中运行的线程数量还没有达到 corePoolSize 大小时,线程池会创建一个新线程执行提交的任务,无论之前创建的线程是否处于空闲状态

2. 当前线程池中运行的线程数量已经达到 corePoolSize 大小时,线程池会把任务加入到等待队列中,直到某一个线程空闲了,线程池会根据我们设置的等待队列规则,从队列中取出一个新的任务执行

3. 如果线程数大于 corePoolSize 数量但是还没有达到最大线程数 maximumPoolSize,并且等待队列已满,则线程池会创建新的线程来执行任务

4. 最后如果提交的任务,无法被核心线程直接执行,又无法加入等待队列,又无法创建“非核心线程”直接执行,线程池将根据拒绝处理器定义的策略处理这个任务

如果你没有为线程池设置 RejectedExecutionHandler。这时线程池会抛出 RejectedExecutionException 异常,拒绝策略

java中的阻塞队列

1.ArrayBlockingQueue: 由数组结构组成的有界阻塞队列

2.LinkedBlockingQueue: 由链表结构组成的有界阻塞队列

3. PriorityBlockingQueue : 支持优先级排序的无界阻塞队列

4. DelayQueue: 使用优先级队列实现的无界阻塞队列

5. synchronousQueue: 不存储元素的阻塞队列

6. LinkedTransferQueue: 由链表结构组成的无界阻塞队列

7. LinkedBlockingDeque: 由链表结构组成的双向阻塞队列

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值