• 参考博客:
    点击!!!!!点击!!!!!点击!!!!!点击!!!!!点击!!!!!点击!!!!!延迟队列详情点击!!主要参考,点击!!!!!
  • 为什么提出线程池?
    • 什么是线程池技术?
    • 什么时候用线程池计数?
    • 线程池的优势:
    • 线程池的设计思路及执行流程:
  • 线程池的结构
    • 线程池之任务的实现方式:
    • 浅谈线程池ThreadPoolExecutor:
      • ThreadPoolExecutor的属性:
      • ThreadPoolThread的构造方法:
        • 七个小矮人之第五个小矮人:任务队列
        • 七个小矮人之第六个小矮人:线程工厂
        • 七个小矮人之第七个小矮人:拒绝策略
      • ThreadPoolThread方法:
        • ThreadPoolThread方法之线程初始化:
        • ThreadPoolThread`方法之线程池关闭:
        • ThreadPoolThread`方法之线程容量调整:
        • ThreadPoolThread`方法之线程池监控:
      • 线程池ThreadPoolThread使用:
    • Executors封装的四种常见的线程池
  • 线程池源码级分析
    • ThreadPoolThread源码解析之execute():
    • ThreadPoolThread源码解析之addWorker():
    • ThreadPoolThread内部类Worker源码解析:
    • ThreadPoolThread源码解析之runWorker():
    • ThreadPoolThread源码解析之getTask():
    • ThreadPoolThread源码解析之processWorkerExit():
    • AbstractExecutorService源码解析之Callable任务带来的异常不输出问题:
  • 到底就结束了对线程池的相关学习,感谢各位大佬的博客借鉴。

为什么提出线程池?

  • 其实很多设计的产生,都源自生活需要,有一句话说的好:科技发展不是因为懒,而是为了节约更多的时间高效率的做更多工作。线程池的产生,也是如此。
  • 在学习的过程中,线程的重要性不言而喻。有时我们需要多次使用线程,既然用到线程,我们就要创建并且销毁线程,而这个创建和销毁的过程都需要映射到操作系统,并且会消耗一定的内存,而内存资源是非常宝贵的,因此其代价是比较高昂的,所以我们就想是否可以不要每次都创建和销毁线程,这时,线程池应运而生。
  • 我们举一个开发过程中的例子:
    • 假设一个服务器一天要处理20000个请求,并且每个请求需要一个单独的线程完成,而每个线程执行的时间非常短,这样就会频繁的创建和销毁线程,这样就大大降低了系统的效率,并且可能出现服务器在为每个请求创建新线程和销毁线程上花费的时间和消耗的系统资源要比处理实际的用户请求的时间和资源更多。
    • 那么有没有一种办法使执行完一个任务,并不被销毁,而是可以继续执行其他的任务呢?
    • 这就是线程池的目的了。线程池为线程生命周期的开销和资源不足问题提供了解决方案。通过对多个任务重用线程,线程创建的开销被分摊到了多个任务上。

什么是线程池技术?

  • “线程池”,顾名思义就是一个线程缓存,线程是稀缺资源,如果被无限制的创建,不仅会消耗系统资源,还会降低系统的稳定性,因此Java中提供线程池对线程进行统一分配、调优和监控;

什么时候用线程池计数?

  • 单个任务处理时间比较短;
  • 需要处理的任务量很大;

线程池的优势:

  • 降低资源消耗: 线程池通常会维护一些线程(数量为 corePoolSize),这些线程被重复使用来执行不同的任务,任务完成后不会销毁。在待处理任务量很大的时候,通过对线程资源的复用,避免了线程的频繁创建与销毁,从而降低了系统资源消耗。
  • 提高响应速度: 由于线程池维护了一批 alive 状态的线程,当任务到达时,不需要再创建线程,而是直接由这些线程去执行任务,从而减少了任务的等待时间。
  • 提高线程的可管理性: 使用线程池可以对线程进行统一的分配,调优和监控

线程池的设计思路及执行流程:

  • 我们通过一个工厂的设计流程来对比线程池(图和思路来自另一篇博客,文章头有引用地址):
  • 通过图我们可以这样进行对比:
    • 工厂流程: 工厂中有固定的一批工人,我们称之为正式员工,一般不会对他们进行裁员,并且大多数订单也是由他们完成,但是如果赶上"双11",那么订单量就会暴涨,我们虽然可以先保存一些订单,但是如果订单量过大,那么可能时间上来不及,这时候我们就要雇佣一些临时工来完成暴增的订单,如果这样还不够,那么我们要认同割爱,放其一些订单了。

      • 总而言之分为4步:
      • 订单1:这一部分由正式工完成; -------------》正式工对应核心线程
      • 订单2:这一部分新增的订单存放在仓库; -------------》仓库对应任务队列
      • 订单3:如果仓库都放满了,这时候要雇佣临时来完成订单; -------------》临时工对应普通线程
      • 订单4:订单太多,不要了;-------------》不要了对应拒绝策列
    • 线程池流程:
      • 任务进来时,首先执行判断,判断当前线程数量(worker)是否小于核心线程(corePoolSize),如果是,创建核心线程并执行任务;
      • 如果不是,则判断任务队列(workQueue)中是否有地方存放该任务,如果有,就将任务保存在任务队列中,等待执行;
      • 如果任务队列满了,在判断当前线程数是否小于最大线程数(maximumPoolSize),如果没有超出这个数量,就创建普通线程(worker)执行任务;
      • 如果超出了,就调用handler实现拒绝策略(RejectedExecutionHandler);
    • 我们对上面的4步做一个流程图来进一步理解线程池:
  • 大体是以上四步,但是还有一些细节需要我们知道,比如调度员对应getTask(),订单对应任务(Runnable),工厂对应 线程池,拒绝策略 有哪几种,任务队列 有哪几种,后面都会有详细的讲解;

线程池的结构

  • 我们先看一下Java线程池框架体系:

  • 通过这两张图我们可以发现,Executor下有一个重要子接口ExecutorService,其中定义了线程池的具体行为:在这里我们先提几个:
    • execute(Runnable command): 执行Ruannable接口实现的任务;
    • submit(task): 可用来提交CallableRunnable任务,并返回代表此任务的Future对象,这是平时学习不太用到的;
    • shutdown(): 使线程池进入shutdown状态,不再接收新任务,但是可以处理任务队列中的任务;
    • shutdownNow(): 使线程池进入shutdownNow状态,什么任务也不执行了;

线程池之任务的实现方式:

  • 我们把任务通过两个接口实现,以有无返回值为区分点,如下: Callable同样是任务,与Runnable接口不同的是:它可以接收泛型,并且执行任务后有返回值
Runnable,Thread,Callable// 实现Runnable接口的类将被Thread执行,表示一个基本的任务,这个相信不用多说了public interface Runnable {public abstract void run();}
//Callable同样是任务,与Runnable接口不同的是:它可以接收泛型,并且执行任务后有返回值public interface Callable<V> {// 相对于run方法的带有返回值的call方法V call() throws Exception;}

浅谈线程池ThreadPoolExecutor:

  • 我们首先看一下ThreadPoolExecutor的属性以及构造方法,因为我们可以通过这个ThreadPoolExecutor来自主设计线程池;

ThreadPoolExecutor的属性:

 //这个属性是用来存放当前运行的        												

大厂之路一由浅入深、并行基础、源码分析一 “J.U.C.L”之线程池(最全,最深,最喜欢)相关推荐

  1. 【Android】Retrofit基础源码分析

    文章目录 流程图 基本使用 1. 创建服务端ApiInterface 2.配置BaseUrl生成Retrofit对象 3.生成服务端ApiInterface对象 4.调用服务端ApiInterface ...

  2. 大厂之路一由浅入深、并行基础、源码分析一 “J.U.C”之collections框架:ConcurrentHashMap扩容迁移等方法的源码分析

    参考文献: 本篇文章主要来源于这篇博客,本人对ConcurrentHashMap的源码之前没有学,虽然看了书但是不涉及这些,所以大部分都来源于观看大神博客的感悟,如果大家需要,可以看一看,也可以点击跳 ...

  3. obs源码分析【五】:音频采集线程

      在第三篇介绍了视频的线程,音频的线程代码也是在那一块儿: if (!ResetAudio())throw "Failed to initialize audio";   音频线 ...

  4. 大厂之路一由浅入深、并行基础、源码分析一 “J.U.C”之collections框架:综述

    参考博客:点击!!! 写这一篇文章的目的,是为了让自己更好的把握框架,来更好的整理自己所学的知识,基本来源于上面这篇文章,也可以说成转载吧,大家可以去那位大神的博客进一步观看,谢谢! Java集合包之 ...

  5. JDK1.8 中 ConcurrentHashMap源码分析(二)元素添加是线程安全的

    上一篇说到了ConcurrentHashMap初始化

  6. idea 线程内存_Java线程池系列之-Java线程池底层源码分析系列(一)

    课程简介: 课程目标:通过本课程学习,深入理解Java线程池,提升自身技术能力与价值. 适用人群:具有Java多线程基础的人群,希望深入理解线程池底层原理的人群. 课程概述:多线程的异步执行方式,虽然 ...

  7. java 线程池 源码_java线程池源码分析

    我们在关闭线程池的时候会使用shutdown()和shutdownNow(),那么问题来了: 这两个方法又什么区别呢? 他们背后的原理是什么呢? 线程池中线程超过了coresize后会怎么操作呢? 为 ...

  8. 技术社区分享|添加FUSD源码分析

    本文由Flow的技术大使FOU编写.他在学习Flow链上稳定币FUSD的过程中总结得出,希望能够给学习FUSD代码的小伙伴一定的启发和帮助.​ 摘要     1. FUSD基础源码分析 2. 重点分析 ...

  9. 02.并发编程(2)Thread类源码分析

    概述 在说线程之前先说下进程,进程和线程都是一个时间段的描述,是CPU工作时间段的描述. 进程,是并发执行的程序在执行过程中分配和管理资源的基本单位,是一个动态概念,竟争计算机系统资源的基本单位.每一 ...

最新文章

  1. LoRa VS NB-IoT,一场物联网时代C位争夺战
  2. 地图上实现高效率绘制海量点的原理
  3. 玩转Google开源C++单元测试框架Google Test系列(gtest)之三 - 事件机制
  4. 最详细的Mac下安装nacos教程来了
  5. Bootstrap 流式布局
  6. 计算机应用管理专业能干什么,计算机应用技术专业可以做什么?
  7. full join 和full outer join_带你了解数据库中JOIN的用法
  8. 基于 Vue 的轻量级静态网站生成器 VuePress
  9. 非double型数值-整型数据类型
  10. 读Pyqt4教程,带你入门Pyqt4 _007
  11. 网络字节序与主机字节序 高低位
  12. c# 两行代码合并pdf文件
  13. 【高等数学】方差的集合意义
  14. 哪个程序猿还没段风花雪月的错过
  15. 语言模型(五)—— Seq2Seq、Attention、Transformer学习笔记
  16. 从苏宁电器到卡巴斯基(第二部)第30篇:我当高校教师的这几年 VI
  17. nodejs+express搭建小程序后台服务器
  18. python试卷三联学院_安徽三联学院期末考试英国文学完整版
  19. 瓜子二手车后台研发实习生面经
  20. ISO转换QCOW2格式

热门文章

  1. Netty系列二、Netty原理篇
  2. 项目管理心得分享九点总结
  3. 别指望灵感,还是要靠汗水 ——“创造性思维”的三个迷信
  4. 《信号完整性揭秘》读书笔记
  5. 微信小程序(二)我的第一个微信小程序(获取用户信息失败)
  6. 《深入理解Android 卷1》读书笔记 (一)—— Android Init之属性服务 (property_service)
  7. 华为策略路由route-policy
  8. 盘点Zookeeper在分布式架构中的应用
  9. 关于树叶的活动设计_幼儿园大班《叶子》主题教案
  10. 什么是“门”电路(电子硬件)