ThreadPoolExecutor里面使用到JUC同步器框架AbstractQueuedSynchronizer、大量的位操作、CAS操作。ThreadPoolExecutor提供了固定活跃线程、额外的线程、任务队列以及拒绝策略这几个重要的功能。下面我们一起来看看Java 线程池ThreadPoolExecutor的原理解析。
1、JUC同步器框架
ThreadPoolExecutor里面使用到JUC同步器框架,主要用于四个方面:
(1)全局锁mainLock成员属性,是可重入锁ReentrantLock类型,主要是用于访问工作线程Worker集合和进行数据统计记录时候的加锁操作。
(2)条件变量termination,Condition类型,主要用于线程进行等待终结awaitTermination()方法时的带期限阻塞。
(3)任务队列workQueue,BlockingQueue类型,任务队列,用于存放待执行的任务。
(4)工作线程,内部类Worker类型,是线程池中真正的工作线程对象。
2、核心线程
这里先参考ThreadPoolExecutor的实现并且进行简化,实现一个只有核心线程的线程池,要求如下:暂时不考虑任务执行异常情况下的处理;任务队列为无界队列;线程池容量固定为核心线程数量;暂时不考虑拒绝策略。
public class CoreThreadPool implements Executor {
private BlockingQueue<Runnable> workQueue;
private static final AtomicInteger COUNTER = new AtomicInteger();
private int coreSize;
private int threadCount = 0;
public CoreThreadPool(int coreSize) {
this.coreSize = coreSize;
this.workQueue = new LinkedBlockingQueue<>();
}
@Override
public void execute(Runnable command) {
if (++threadCount <= coreSize) {
new Worker(command).start();
} else {
try {
workQueue.put(command);
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}
}
private class Worker extends Thread {
private Runnable firstTask;
public Worker(Runnable runnable) {
super(String.format("Worker-%d", COUNTER.getAndIncrement()));
this.firstTask = runnable;
}
@Override
public void run() {
Runnable task = this.firstTask;
while (null != task || null != (task = getTask())) {
try {
task.run();
} finally {
task = null;
}
}
}
}
private Runnable getTask() {
try {
return workQueue.take();
} catch (InterruptedException e) {
throw new IllegalStateException(e);
}
}
public static void main(String[] args) throws Exception {
CoreThreadPool pool = new CoreThreadPool(5);
IntStream.range(0, 10)
.forEach(i -> pool.execute(() ->
System.out.println(String.format("Thread:%s,value:%d", Thread.currentThread().getName(), i))));
Thread.sleep(Integer.MAX_VALUE);
}
}
某次运行结果如下:
Thread:Worker-0,value:0
Thread:Worker-3,value:3
Thread:Worker-2,value:2
Thread:Worker-1,value:1
Thread:Worker-4,value:4
Thread:Worker-1,value:5
Thread:Worker-2,value:8
Thread:Worker-4,value:7
Thread:Worker-0,value:6
Thread:Worker-3,value:9
设计此线程池的时候,核心线程是懒创建的,如果线程空闲的时候则阻塞在任务队列的take()方法,其实对于ThreadPoolExecutor也是类似这样实现,只是如果使用了keepAliveTime并且允许核心线程超时则会使用BlockingQueue#poll进行轮询代替永久阻塞。
3、其他附加功能
构建ThreadPoolExecutor实例的时候,需要定义maximumPoolSize(线程池最大线程数)和corePoolSize(核心线程数)。当任务队列是有界的阻塞队列,核心线程满负载,任务队列已经满的情况下,会尝试创建额外的maximumPoolSize - corePoolSize个线程去执行新提交的任务。当ThreadPoolExecutor这里实现的两个主要附加功能是:
(1)一定条件下会创建非核心线程去执行任务,非核心线程的回收周期(线程生命周期终结时刻)是keepAliveTime,线程生命周期终结的条件是:下一次通过任务队列获取任务的时候并且存活时间超过keepAliveTime。
(2)提供拒绝策略,也就是在核心线程满负载、任务队列已满、非核心线程满负载的条件下会触发拒绝策略。
以上就是Java 线程池ThreadPoolExecutor的原理解析,大家都看懂了吗?如果想要深入学习更多关于Java 线程池的内容,欢迎大家在博学谷报名在线课程进行学习~
— 申请免费试学名额 —
在职想转行提升,担心学不会?根据个人情况规划学习路线,闯关式自适应学习模式保证学习效果
讲师一对一辅导,在线答疑解惑,指导就业!
相关推荐 更多
Java开发语言与C语言C++的区别是什么?
从各大机构的编程语言排行榜我们可以了解。目前世界范围内Java开发语言与C语言C++基本长期占领开发语言榜单的前三位。那这三门语言之间有什么区别呢?
7140
2019-08-08 14:18:09
自学Java开发能找到工作吗?
自学Java开发能找到工作吗?具体问题具体分析,因此这需要结合个人的学习能力和学习进度分析。一般来讲,自学Java有这样的问题:没有牢固掌握系统全面的理论知识;学习内容没有与时俱进,不符合企业的对技能的需求;空有理论知识,缺乏实践经验。以上这些问题就是大家在自学完Java后,找不到工作的主要原因。下面小编来讲讲如何解决这些自学的问题。
2801
2019-10-09 17:37:43
GC垃圾回收学习笔记整理
只要掌握了GC垃圾回收的相关知识点,程序员在工作中就不用担心内存管理了,因为垃圾收集器会自动进行管理。本文为大家整理了GC垃圾回收的学习笔记,主要内容包括了判断回收条件,虚拟机频繁full GC的解决对策以及经典的垃圾回收算法。大家要是对GC垃圾回收的相关学习学习感兴趣,就接着看下去吧!
2331
2020-03-26 22:20:37
JavaEE实战项目手机快速登录讲解
今天要讲解的JavaEE实战项目是一款应用于健康管理机构的业务系统,它叫做传智健康,能够实现健康管理机构工作内容可视化、会员管理专业化、 健康评估数字化、健康干预流程化、知识库集成化,从而提高健康管理师的工作效率,加强与会员间的互动,增强管理者对健康管理机构运营情况的了解。下面我们来一起看看传智健康实战项目的移动端开发内容,主要包括了需求分析和手机快速登录。
2559
2020-04-22 12:06:56
女生学Java好就业吗?适合编程吗?
女生学Java好就业吗?目前有不少女生学习Java开发,但要结合自身的情况,先了解自己适不适合去学习Java,不要盲目的选择不适合自己的Java培训班进行学习。只要肯下功夫钻研,多看、多想、多练都可能成为一名优秀的Java开发工程师,女生的实力也是不容置疑的,且女生学Java还具备一定的优势。
2934
2021-02-03 15:58:09
热门文章
- 缓存淘汰策略有几种?要怎么用?
- 软件测试极速就业班课程怎么样?零基础能学吗
- 狂野架构师学习效果好不好?互联网Java架构师前景怎么样?
- 博学谷狂野大数据学习效果好不好?课程怎么样?
- Redis持久化机制实现原理是什么?流程是什么?
- 万物互联是什么?会带来哪些改变?
- MySQL索引种类有哪些?底层实现原是什么
- 零基础转行IT互联网岗位月入过万需要多久?
- 从0搭建后端技术涉及到哪些知识点?
- 疫情下的医疗行业如何快速响应的?互联网技术功不可没 查看更多
扫描二维码,了解更多信息
