并发编程系列之线程池工厂类:Executors

2023-10-31

前言

上节讲了讲自定义线程池,今天我们来聊聊线程池框架,在实际开发中我们还是基本使用线程框架Executor给我们提供的一些工具类,Java提供的Executor都在JUC(java.util.concurrent)包下面,主要包括:线程池工厂类Executors,线程池实现类ThreadPoolExecutor等,今天呢我们主要聊聊Executors,看看通过Executors我们可以做什么?OK,不多说废话,我们马上进入今天的主题,让我们扬帆起航,开启今天的并发之旅吧。

 

什么是Executors?

Executors,扮演的是线程工厂的角色,一定要与Executor相区分开,Executors只是Executor框架中的一个工厂类而已,通过Executors我们可以创建特定功能的线程池(ThreadPoolExecutor),通过这句话你是不是对Executors和ThreadPoolExecutor的关系有了一定的认识,这两个都是Executor框架中的一部分(关于Executor框架的各个成员组成这里就先不做说明,今天主要是学会怎么使用线程工厂创建线程池)。

 

如何使用Executors?

线程池ThreadPoolExecutor通常都是通过Executors来创建的,我们可以根据自己的需求创建下面几种不同作用的线程池:

// 创建一个固定数量的线程池
ExecutorService ExecutorService1 = Executors.newFixedThreadPool(10);
// 返回一个可根据实际情况调整线程个数的线程池
ExecutorService ExecutorService2 = Executors.newCachedThreadPool();
// 创建一个线程数量为1的线程池
ExecutorService ExecutorService3 = Executors.newSingleThreadExecutor();
// 返回一个ScheduledExecutorService对象,该对象也是调用父类的线程池方法,类似newFixedThreadPool
ScheduledExecutorService ScheduledExecutorService = Executors.newScheduledThreadPool(5);

线程池的使用之前讲自定义线程池已经说过了,主要也就是:

  • execute向线程池提交任务

  • shutdown和shutdownNow关闭线程池

 

newFixedThreadPool:该方法返回一个固定数量的线程池,该方法的线程数量始终不变,当有任务提交时,若线程池中有空闲线程,则立即执行,若没有,则会被缓存在一个任务队列中等待有空闲的线程再去执行;(核心线程数等于最大线程数,默认空闲时间为0,空闲立马销毁),该方法有2个实现,我们看下面源码:

public static ExecutorService newFixedThreadPool(int nThreads) {
       return new ThreadPoolExecutor(nThreads, nThreads,
                                     0L, TimeUnit.MILLISECONDS,
                                     new LinkedBlockingQueue<Runnable>());
   }

public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) {
       return new ThreadPoolExecutor(nThreads, nThreads,
                                     0L, TimeUnit.MILLISECONDS,
                                     new LinkedBlockingQueue<Runnable>(),
                                     threadFactory);
   }

再分别看下这2个方法在线程池中的实现:

// 我们会发现没有传入线程工厂的方法调用了一个默认的线程工厂
public ThreadPoolExecutor(int corePoolSize,
                             int maximumPoolSize,
                             long keepAliveTime,
                             TimeUnit unit,
                             BlockingQueue<Runnable> workQueue) {
       this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
            Executors.defaultThreadFactory(), defaultHandler);
   }

// 而有传入线程工厂的方法调用自己传入的线程工厂
public ThreadPoolExecutor(int corePoolSize,
                             int maximumPoolSize,
                             long keepAliveTime,
                             TimeUnit unit,
                             BlockingQueue<Runnable> workQueue,
                             ThreadFactory threadFactory) {
       this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
            threadFactory, defaultHandler);
   }

 

newSingleThreadExecutor:创建一个线程数量为1的线程池,若空闲则执行,否则入队列等待被执行;(核心线程数量为1,最大线程数量也为1,空闲等待时间为0),该方法也有2个实现,一个带自定义的线程工厂,一个不带:

public static ExecutorService newSingleThreadExecutor() {
       return new FinalizableDelegatedExecutorService
           (new ThreadPoolExecutor(1, 1,
                                   0L, TimeUnit.MILLISECONDS,
                                   new LinkedBlockingQueue<Runnable>()));
   }

public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
       return new FinalizableDelegatedExecutorService
           (new ThreadPoolExecutor(1, 1,
                                   0L, TimeUnit.MILLISECONDS,
                                   new LinkedBlockingQueue<Runnable>(),
                                   threadFactory));
   }

 

newCachedThreadPool:返回一个可根据实际情况调整线程个数的线程池,不限制最大线程数量,若有任务则没线程时则创建线程,每个线程空闲等待时间为60秒,60秒后如果该线程没有任务可执行,则被回收;(核心线程数量为0,最大线程数量为最大,空闲等待时间为60s)

public static ExecutorService newCachedThreadPool() {
       return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                     60L, TimeUnit.SECONDS,
                                     new SynchronousQueue<Runnable>());
   }

  public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) {
       return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                                     60L, TimeUnit.SECONDS,
                                     new SynchronousQueue<Runnable>(),
                                     threadFactory);
   }

本文由“壹伴编辑器”提供技术支持

newScheduledThreadPool:返回一个ScheduledExecutorService对象,该线程池可以指定线程数量

// 返回一个ScheduledExecutorService对象
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
       return new ScheduledThreadPoolExecutor(corePoolSize);
   }

// 调了父类super的方法里面还是一个ThreadPoolExecutor
public ScheduledThreadPoolExecutor(int corePoolSize) {
       super(corePoolSize, Integer.MAX_VALUE, 0, TimeUnit.NANOSECONDS,
             new DelayedWorkQueue());
   }
// 父类super中的ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,
                             int maximumPoolSize,
                             long keepAliveTime,
                             TimeUnit unit,
                             BlockingQueue<Runnable> workQueue) {
       this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
            Executors.defaultThreadFactory(), defaultHandler);
   }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

并发编程系列之线程池工厂类:Executors 的相关文章

  • Java并发编程实战——并发容器之ThreadLocal及其内存泄漏问题

    文章目录 ThreadLocal的简介 ThreadLocal的实现原理 ThreadLocalMap详解 ThreadLocal内存泄漏问题 ThreadLocal的使用场景 ThreadLocal的简介 之前写过用ThreadLocal
  • Java 线程池ExecutorService 等待队列问题

    本人博客原地址 Java 线程池ExecutorService 等待队列问题 创作时间 2019 09 30 11 12 35 1 首先看下Executor获取线程池 这样方式 可以设置线程池的大小 但是了解线程池的内部原理的情况下 这样的
  • 浅析多线程中的各种锁

    高并发的场景下 如果选对了合适的锁 则会大大提高系统的性能 否则性能会降低 所以 知道各种锁的开销 以及应用场景是很有必要的 文章目录 常用的各种锁 互斥锁与自旋锁 互斥锁 自旋锁 读写锁 乐观锁与悲观锁 本文小结 常用的各种锁 多线程访问
  • 源码分析【ReentrantLock】原理

    ReentrackLock底层原理 ReentrackLock介绍 非公平锁VS公平 非公平锁 公平锁 可打断VS不可打断 不可打断 默认 可打断模式 锁超时 条件变量 如何在synchronized和ReentrantLock之间进行选择
  • 并发编程JMM系列之重排序和顺序一致性

    前言 昨天我们接触到了什么是Java内存模型以及两种Java并发模型 并对JMM有了一些初步的认识和了解 我们在上节有提到JMM的重排序规则 但是讲的不详细 今天我们再重点聊下重排序这个东西 以及顺序一致性内存模型 OK 开始我们今天的并发
  • 并发编程系列——6线程池核心原理分析

    学习目标 线程池的作用 jdk给我们提供了哪几种常用线程池 线程池有哪几大核心参数 线程池的拒绝策略有哪些 线程中阻塞队列的作用 线程池的工作流程 线程池的设计思维 线程池中的阻塞队列如果用默认的 会有哪些问题 线程池的工作状态有哪些 线程
  • 场景题之最快返回结果

    场景题之最快返回结果 问题描述 输入中文 最快从百度翻译 谷歌翻译 有道翻译获取结果返回 代码实现 思路 采用CompletableFuture实现 多个CompletableFuture可以串行执行 也可以并行执行 其中anyOf 方法只
  • 面试官:说说CountDownLatch,CyclicBarrier,Semaphore的原理?

    CountDownLatch CountDownLatch适用于在多线程的场景需要等待所有子线程全部执行完毕之后再做操作的场景 举个例子 早上部门开会 有人在上厕所 这时候需要等待所有人从厕所回来之后才能开始会议 public class
  • 并发编程系列之volatile内存语义

    前言 前面介绍顺序一致性模型时 我们提到了程序如果正确的同步就会具备顺序一致性 这里所说的同步泛指广义上的同步 其中包括就包括同步原语volatile 那么volatile声明的变量为什么就能保证同步呢 这又是如何实现的呢 今天就让我们一起
  • C++ std::thread多线程详解

    c 多线程详解 一 std thread线程创建 1 函数指针 2 Lambda函数 3 functor Funciton Object 4 非静态成员函数 5 静态成员函数 二 std thread线程停止 1 join函数 2 deta
  • 上下文切换理解以及减少方法

    并发编程面临着上下文切换 死锁等问题 尤其在少量数据的情况下 并发可能因为线程的创建和上下文切换的开销等问题 甚至比串行执行的速度更慢 文章目录 上下文切换定义 例子理解 减少上下文切换的方法 无锁并发编程 CAS算法 使用最少线程 协程
  • Callable接口详解

    Callable接口详解 Callable 返回结果并且可能抛出异常的任务 优点 可以获得任务执行返回值 通过与Future的结合 可以实现利用Future来跟踪异步计算的结果 Runnable和Callable的区别 1 Callable
  • JUC学习笔记及拓展

    本文为自己整理的学习笔记及学习心得 大纲取自尚硅谷的JUC视频 感兴趣的小伙伴可以去B站自学 JUC学习笔记及拓展 Java JUC 1 Java JUC简介 2 volatile 关键字 内存可见性 2 1 内存可见性 2 2 volat
  • C/C++基于线程的并发编程(二):线程安全和线程锁

    线程安全 所谓线程安全不是指线程的安全 而是指内存的安全 线程是由进程所承载 所有线程均可访问进程的上下文 意味着所有线程均可访问在进程中的内存空间 这也是线程之间造成问题的潜在原因 当多个线程读取同一片内存空间 变量 对象等 时 不会引起
  • Java并发编程-第二章

    以下内容来自 Java并发编程 书籍第二章 补充 1 volatile的有序性 volatile通过内存屏障实现禁止指令重排序保证有序性 硬件层面的内存屏障分为Load Barrier 和 Store Barrier即读屏障和写屏障 2 同
  • ReentrantLock实现PV操作-模拟多线程竞争数据库连接池资源场景

    使用ReentrantLock Condition模拟PV操作 实现多线程竞争数据库连接池资源 资源耗尽后阻塞等待 归还资源后唤醒阻塞线程的场景 代码中为10个线程竞争5个数据库连接资源 ConnectionPool class 连接池 C
  • shell编程笔记3--shell并发

    shell编程笔记3 shell并发 shell编程笔记3 shell并发 介绍 并发方法 1 简单后台方式 2 普通控制并发量方式 3 通过管道控制并发量 参考文献 shell编程笔记3 shell并发 介绍 在shell中适当使用并发功
  • ThreadPoolExecutor源码解析

    ThreadPoolExecutor源码解析 一 新建线程池的是构造方法 public ThreadPoolExecutor int corePoolSize int maximumPoolSize long keepAliveTime T
  • 死锁产生条件和解决办法

    死锁 死锁产生的四个条件 产生死锁必须同时满足以下四个条件 只要其中任一条件不成立 死锁就不会发生 互斥条件 线程要求对所分配的资源 如打印机 进行排他性控制 即在一段时间内某资源仅为一个线程所占有 此时若有其他线程请求该资源 则请求线程只
  • Java并发编程之设计模式

    同步模式之保护性暂停 1 定义 即 Guarded Suspension 用在一个线程等待另一个线程的执行结果 要点 有一个结果需要从一个线程传递到另一个线程 让他们关联同一个 GuardedObject 如果有结果不断从一个线程到另一个线

随机推荐

  • socket实验——stmp简单邮件代理

    Q A 1 email应用的组成 邮件客户端 邮件服务器 SMTP协议 2 为什么email要使用客户端服务器的结构 而不是直接在用户间建立连接 想象自己不在线和对方不在线的情况 3 SMTP协议 简单邮件传输协议 传输层协议 TCP 端口
  • mui ajax 懒加载,MUI懒加载 - 前端小谢的个人空间 - OSCHINA - 中文开源技术交流社区...

    在各种列表中 有些需要大量的图片 在这些列表结构中使用懒加载可以很快提高加载速度 我们需要引入mui lazyload js和mui lazyload img js两个文件 还有占位图 懒加载 window page fk fn getDo
  • windows环境下部署以太坊私有链

    1 部署环境 1 Windows操作系统 window10 X64 2 以太坊客户端 geth windows amd64 1 8 3 329ac18e exe 3 以太坊钱包 Ethereum Wallet win64 0 9 3 zip
  • 《C++ Primer》13.1.2节练习

    练习13 6 拷贝赋值运算符本身是一个重载的赋值运算符 定义为类的成员函数 左侧运算对象绑定到隐含的this参数 而右侧运算对象是所属类类型的 作为函数的参数 函数返回指向其左侧运算对象的引用 当对类对象进行赋值时 会使用拷贝赋值运算符 通
  • 网络端口详解

    0端口 无效端口 通常用于分析操作系统 1端口 传输控制协议端口服务多路开关选择器 2端口 管理实用程序 3端口 压缩进程 5端口 远程作业登录 7端口 回显 9端口 丢弃 11端口 在线用户 13端口 时间 17端口 每日引用 18端口
  • C#中GDI绘制高质量平滑图形实例

    protected override void OnPaint PaintEventArgs e try Graphics g e Graphics 获取绘制对象 设置参数 g SmoothingMode System Drawing Dr
  • k8s部署nginx实例、iptables开放端口

    1 运行nginx实例 kubectl run nginx image nginx replicas 2 port 80 2 查看pod root localhost kubectl get pods NAME READY STATUS R
  • 【计算机毕业选题】2023~2024计算机毕业设计选题篇-选题推荐

    学弟学妹们 大家好 这里是JAVA编码选手的博客空间 一年一度的计算机专业毕业设计又要开始了 大四的你们准备好选题了吗 先介绍一下自己 本人软件工程毕业 5年软件开发经验 计算机程序设计 java程序 Java代做 微服务SSM Java管
  • linux删除大量文件时,报错  argument list too long 

    linux删除大量文件时 报错 argument list too long 原因 删除数据量太大 解决办法 1 删除某个文件夹下 所有文件 cd 到需要删除的文件夹内 删除所有文件 ls xargs rm r 执行完后 可能有些文件删除不
  • COMP 9417 T2_2021 Lesson 8

    贝叶斯 numeric attributes 决策树 优点 某种形式的树可能仍然是最流行的data mining 易于理解 易于实施 易于使用 可以分类可以回归 可用于大数据的处理 例子 例子 在N中需要多少个M来分类 N个特征 thres
  • MeshLab相关&纹理贴图

    安装MeshLab sudo apt get install meshlab 操作 旋转视图 鼠标左键 拖动 缩放视图 滑动鼠标滚轮 shift 左键 平移视图 鼠标滚轮按钮 拖动 指定旋转 轨迹球中心 鼠标左键双击模型特定点 改变界面左下
  • python爬虫什么意思-终于知道python爬虫是什么意思

    爬虫过程中也会经历一些绝望啊 比如被网站封IP 比如各种奇怪的验证码 userAgent访问限制 各种动态加载等等 下面是小编为您整理的关于python爬虫是什么意思 希望对你有所帮助 python爬虫是什么意思 python爬虫即网络爬虫
  • ndarray对象——创建

    首先需要创建数组才能对其进行运算和操作 可以通过arrray 函数传递Python的序列对象来创建数组 如果传递的是多层嵌套的序列 将创建多维数组 下例变量中的c import numpy as np a np array 1 2 3 4
  • 信用卡评分模型(R语言)

    信用卡评分 2016年1月10日 一 数据准备 1 问题的准备 目标 要完成一个评分卡 通过预测某人在未来两年内将会经历财务危机的可能性来提高信用评分的效果 帮助贷款人做出最好的决策 背景 银行在市场经济中起到至关重要的作用 他们决定谁在什
  • 1.业务架构·应用架构·数据架构实战 --- 架构实践全景图

    第1章 架构实践全景图 1 1 战略 BA DA AA TA五者的关系 业务架构是跨系统的业务架构蓝图 应用架构 数据架构 技术架构是解决方案的不同方面 BA Business Architecture 业务架构 DA Data Archi
  • 计算机网络-应用层协议3(SMTP、POP3、IMAP)

    1 SMTP 简单邮件传输协议 1 1 SMTP的基本操作 假设Alice想给Bob发送一封简单的ASCII报文 Alice调用她的邮件代理程序并提供Bob的邮件地址 bob someschool edu 撰写报文 然后指示用户代理发送该报
  • 【2022版】Golang面试题目全网超全超详细的口语化解答总结

    2022版 Golang面试题目全网超全总结 1 特性篇 1 1 Golang 使用什么数据类型 1 2 字符串的小问题 1 3 数组定义问题 1 4 内存四区 1 5 Go 支持什么形式的类型转换 1 6 空结构体的作用 1 7 单引号
  • 完全理解图(上)——图的概念、存储及遍历

    术语 图 由结点的有穷集合V和边的集合E组成 在图中 结点常被称为顶点 若两个顶点之间存在一条边 则表示两个顶点相邻 有向图 图的每条边都有方向 无向图 图的每条边没有方向 弧 有向图中 常将边称为弧 含箭头的一端称为弧头 另一端称为弧尾
  • spark机器学习训练模型示例(一)

    利用逻辑回归建立模型 建立训练集和测试集 from pyspark ml import Pipeline from pyspark ml classification import LogisticRegression from pyspa
  • 并发编程系列之线程池工厂类:Executors

    前言 上节讲了讲自定义线程池 今天我们来聊聊线程池框架 在实际开发中我们还是基本使用线程框架Executor给我们提供的一些工具类 Java提供的Executor都在JUC java util concurrent 包下面 主要包括 线程池