并发编程之线程池的底层原理的详细解析

简介: 并发编程之线程池的底层原理的详细解析

线程池的底层原理

Executors源码:

 

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                                      0L, TimeUnit.MILLISECONDS,
                                      new LinkedBlockingQueue<Runnable>());
    }
    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }
    public static ExecutorService newCachedThreadPool() {
        return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                      60L, TimeUnit.SECONDS,
                                      new SynchronousQueue<Runnable>());
    }
    public ThreadPoolExecutor(int corePoolSize,     //线程池中的常驻核心线程数
                              int maximumPoolSize,  //线程池能容纳同时执行的最大线程数,此值必须大于等于1
                              long keepAliveTime,   //多余的空闲线程的存活时间,当前池中线程数量超过corePoolSize时,当空闲时间达到keepAliveTime时,多余线程就会被销毁到只剩下corePoolSize为止
                              TimeUnit unit,        //keepAliveTime的单位
                              BlockingQueue<Runnable> workQueue,    //任务队列,被提交但尚未执行的任务
                              ThreadFactory threadFactory,          //创建线程的工厂,默认即可
                              RejectedExecutionHandler handler      //拒绝策略,当队列满(maximumPoolSize)时,根据该handler决定如何拒绝请求执行的runnable
                             ) { 
        .....
            ....
                ...
    }

线程池工作原理:

线程池工作图解析:

线程池工作流程:

线程池工作流程:

1、在创建了线程池后,开始等待请求。

2、当调用execute()方法添加一个请求任务时,线程池会做出如下判断:

2.1如果正在运行的线程数量小于corePoolSize,那么马上创建线程运行这个任务;

2.2如果正在运行的线程数量大于或等corePoolSize,那么将这个任务放入队列;

2.3如果这个时候队列满了且正在运行的线程数量还小于maximumPoolSize,那么还是要创建非核心线程立刻运行这个任 务;

2.4如果队列满了且正在运行的线程数量大于或等于maximumPoolSize,那么线程池会启动饱和拒绝策略来执行。

3、当一个线程完成任务时,它会从队列中取下一个任务来执行。

4、当一个线程无事可做超过一定的时间(keepAliveTime)时,线程会判断:

如果当前运行的线程数大于corePoolSize,那么这个线程就被停掉。所以线程池的所有任务完成后,它最终会收缩

corePoolSize的大小。

注意:

在工作中单一的/固定的/可变的三种创建线程池的方法哪个用的多?

答: 一个都不用

OOM java虚拟机内存溢出异常


相关文章
|
6天前
|
SQL 开发框架 .NET
高级主题:Visual Basic 中的多线程和并发编程
【4月更文挑战第27天】本文深入探讨了Visual Basic中的多线程和并发编程,阐述了其基本概念,如何使用`System.Threading.Thread`类创建线程,以及借助`ThreadPool`、`Monitor`和`SyncLock`进行同步管理。文章还提到了多线程编程面临的挑战如竞态条件、死锁和资源竞争,并介绍了VB的异步编程、TPL和并发集合等高级技术。通过实例展示了多线程在文件处理、网络通信和图像处理中的应用,并给出了多线程编程的最佳实践。总之,理解并掌握VB的多线程和并发编程能有效提升应用程序的性能和响应能力。
|
3天前
|
Dart 前端开发 安全
【Flutter前端技术开发专栏】Flutter中的线程与并发编程实践
【4月更文挑战第30天】本文探讨了Flutter中线程管理和并发编程的关键性,强调其对应用性能和用户体验的影响。Dart语言提供了`async`、`await`、`Stream`和`Future`等原生异步支持。Flutter采用事件驱动的单线程模型,通过`Isolate`实现线程隔离。实践中,可利用`async/await`、`StreamBuilder`和`Isolate`处理异步任务,同时注意线程安全和性能调优。参考文献包括Dart异步编程、Flutter线程模型和DevTools文档。
【Flutter前端技术开发专栏】Flutter中的线程与并发编程实践
|
3天前
|
存储 芯片
【期末不挂科-单片机考前速过系列P11】(第十一章:15题速过串行口的工作原理和应用)经典例题盘点(带图解析)
【期末不挂科-单片机考前速过系列P11】(第十一章:15题速过串行口的工作原理和应用)经典例题盘点(带图解析)
【期末不挂科-单片机考前速过系列P10】(第十章:11题中断系统的工作原理及应用)经典例题盘点(带图解析)
【期末不挂科-单片机考前速过系列P10】(第十章:11题中断系统的工作原理及应用)经典例题盘点(带图解析)
|
3天前
|
C语言 C++
【期末不挂科-单片机考前速过系列P1】(第一章:27题搞定单片机&其工作原理)经典例题盘点【选择题&判断题&填空题】(带图解析)
【期末不挂科-单片机考前速过系列P1】(第一章:27题搞定单片机&其工作原理)经典例题盘点【选择题&判断题&填空题】(带图解析)
|
3天前
|
安全 调度 Swift
【Swift开发专栏】Swift中的多线程与并发编程
【4月更文挑战第30天】本文探讨Swift中的多线程与并发编程,分为三个部分:基本概念、并发编程模型和最佳实践。介绍了线程、进程、并发与并行、同步与异步的区别。Swift的并发模型包括GCD、OperationQueue及新引入的结构体Task和Actor。编写高效并发代码需注意任务粒度、避免死锁、使用线程安全集合等。Swift 5.5的并发模型简化了异步编程。理解并掌握这些知识能帮助开发者编写高效、安全的并发代码。
|
4天前
|
JavaScript 前端开发 算法
vue生命周期函数原理解析,vue阻止事件冒泡方法实现
vue生命周期函数原理解析,vue阻止事件冒泡方法实现
|
4天前
|
安全 Java 开发者
构建高效微服务架构:后端开发的新范式Java中的多线程并发编程实践
【4月更文挑战第29天】在数字化转型的浪潮中,微服务架构已成为软件开发的一大趋势。它通过解耦复杂系统、提升可伸缩性和促进敏捷开发来满足现代企业不断变化的业务需求。本文将深入探讨微服务的核心概念、设计原则以及如何利用最新的后端技术栈构建和部署高效的微服务架构。我们将分析微服务带来的挑战,包括服务治理、数据一致性和网络延迟问题,并讨论相应的解决方案。通过实际案例分析和最佳实践的分享,旨在为后端开发者提供一套实施微服务的全面指导。 【4月更文挑战第29天】在现代软件开发中,多线程技术是提高程序性能和响应能力的重要手段。本文通过介绍Java语言的多线程机制,探讨了如何有效地实现线程同步和通信,以及如
|
4天前
|
芯片
EDA设计:原理、实践与代码深度解析
EDA设计:原理、实践与代码深度解析
15 2
|
4天前
|
算法 计算机视觉 Python
DSP技术深度解析:原理、实践与应用
DSP技术深度解析:原理、实践与应用
12 1

推荐镜像

更多