高并发之线程池

本文深入探讨了Java线程池的工作原理,包括shutdownNow()和interruptIfStarted()的实现,以及TIDYING和TERMINATED状态的区别。此外,还详细介绍了线程池的四种拒绝策略:AbortPolicy,CallerRunsPolicy,DiscardPolicy和DiscardOldestPolicy,并提供了相关示例程序。" 52042381,5619033,AutoCAD数据库交互:导入与导出详解,"['AutoCAD开发', '数据库操作', '图形文件处理']
摘要由CSDN通过智能技术生成

1.实现原理

下图所示为线程池的实现原理:调⽤⽅不断地向线程池中提交任务;线程池中有⼀组线程,不断地从队列中取任
务,这是⼀个典型的⽣产者 消费者模型。

 

要实现这样⼀个线程池,有⼏个问题需要考虑:
1. 队列设置多⻓?如果是⽆界的,调⽤⽅不断地往队列中放任务,可能导致内存耗尽。如果是有界的,当队列
满了之后,调⽤⽅如何处理? 2. 线程池中的线程个数是固定的,还是动态变化的?
3. 每次提交新任务,是放⼊队列?还是开新线程?
4. 当没有任务的时候,线程是睡眠⼀⼩段时间?还是进⼊阻塞?如果进⼊阻塞,如何唤醒?
针对问题 4 ,有 3 种做法:
1. 不使⽤阻塞队列,只使⽤⼀般的线程安全的队列,也⽆阻塞 / 唤醒机制。当队列为空时,线程池中的线程只能
睡眠⼀会⼉,然后醒来去看队列中有没有新任务到来,如此不断轮询。
2. 不使⽤阻塞队列,但在队列外部、线程池内部实现了阻塞 / 唤醒机制。
3. 使⽤阻塞队列。
很显然,做法 3 最完善,既避免了线程池内部⾃⼰实现阻塞 / 唤醒机制的麻烦,也避免了做法 1 的睡眠 / 轮询带来的
资源消耗和延迟。正因为如此,接下来要讲的 ThreadPoolExector/ScheduledThreadPoolExecutor 都是基于阻塞队列
来实现的,⽽不是⼀般的队列,⾄此,各式各样的阻塞队列就要派上⽤场了。
2.线程池的类继承体系
在这⾥,有两个核⼼的类: ThreadPoolExector ScheduledThreadPoolExecutor ,后者不仅可以执⾏某个
任务,还可以周期性地执⾏任务。 向线程池中提交的每个任务,都必须实现 Runnable 接⼝,通过最上⾯的 Executor 接⼝中的
execute(Runnable command) 向线程池提交任务。
然后,在 ExecutorService 中,定义了线程池的关闭接⼝ shutdown() ,还定义了可以有返回值的任务,也就
Callable ,后⾯会详细介绍。
3. ThreadPoolExecutor
基于线程池的实现原理,下⾯看⼀下 ThreadPoolExector 的核⼼数据结构。
public class ThreadPoolExecutor extends AbstractExecutorService {
 //...
 private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0));
 // 存放任务的阻塞队列
 private final BlockingQueue<Runnable> workQueue;
 // 对线程池内部各种变量进⾏互斥访问控制
 private final ReentrantLock mainLock = new ReentrantLock();
 // 线程集合
 private final HashSet<Worker> workers = new HashSet<Worker>();
 //...
}
每⼀个线程是⼀个 Worker 对象。 Worker ThreadPoolExector 的内部类,核⼼数据结构如下:
private final class Worker extends AbstractQueuedSynchronizer implements Runnable {
 // ...
 final Thread thread; // Worker封装的线程
 Runnable firstTask; // Worker接收到的第1个任务
 volatile long completedTasks; // Worker执⾏完毕的任务个数
 // ...
}

 

由定义会发现, Worker 继承于 AQS ,也就是说 Worker 本身就是⼀把锁。这把锁有什么⽤处呢?⽤于线程池的关
闭、线程执⾏任务的过程中。
4.核⼼配置参数解释
ThreadPoolExecutor在其构造⽅法中提供了⼏个核⼼配置参数,来配置不同策略的线程池
上⾯的各个参数,解释如下:
1. corePoolSize :在线程池中始终维护的线程个数。
2. maxPoolSize :在 corePooSize 已满、队列也满的情况下,扩充线程⾄此值。
3. keepAliveTime/TimeUnit maxPoolSize 中的空闲线程,销毁所需要的时间,总线程数收缩回
corePoolSize
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值