JAVA多线程(二十一)Java多线程之SingleThreadExecutor单线程化线程池

2023-05-16

1.JAVA多线程(二十一)Java多线程之SingleThreadExecutor单线程化线程池

1.1 单线程化线程池SingleThreadExecutor

   SingleThreadExecutor 是只有一个线程的线程池。通过源代码查看SingleThreadExecutor实现:

    /**
     * Creates an Executor that uses a single worker thread operating
     * off an unbounded queue. (Note however that if this single
     * thread terminates due to a failure during execution prior to
     * shutdown, a new one will take its place if needed to execute
     * subsequent tasks.)  Tasks are guaranteed to execute
     * sequentially, and no more than one task will be active at any
     * given time. Unlike the otherwise equivalent
     * {@code newFixedThreadPool(1)} the returned executor is
     * guaranteed not to be reconfigurable to use additional threads.
     *
     * @return the newly created single-threaded Executor
     */
    public static ExecutorService newSingleThreadExecutor() {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>()));
    }

    /**
     * Creates an Executor that uses a single worker thread operating
     * off an unbounded queue, and uses the provided ThreadFactory to
     * create a new thread when needed. Unlike the otherwise
     * equivalent {@code newFixedThreadPool(1, threadFactory)} the
     * returned executor is guaranteed not to be reconfigurable to use
     * additional threads.
     *
     * @param threadFactory the factory to use when creating new
     * threads
     *
     * @return the newly created single-threaded Executor
     * @throws NullPointerException if threadFactory is null
     */
    public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) {
        return new FinalizableDelegatedExecutorService
            (new ThreadPoolExecutor(1, 1,
                                    0L, TimeUnit.MILLISECONDS,
                                    new LinkedBlockingQueue<Runnable>(),
                                    threadFactory));
    }

    /**
     * Creates a {@code LinkedBlockingQueue} with a capacity of
     * {@link Integer#MAX_VALUE}.
     */
    public LinkedBlockingQueue() {
        this(Integer.MAX_VALUE);
    }

在SingleThreadExecutor实现中:

  • corePoolSize && maximumPoolSize,corePoolSize 和 maximumPoolSize 都被设置为:1。
  • keepAliveTime => keepAliveTime为0,意味着多余的空闲线程会被立即终止。
  • workQueue => 采用无界队列LinkedBlockingQueue作为线程池的工作队列(队列的容量为Integer.MAX_VALUE),会在循环中反复从LinkedBlockingQueue获取任务来执行。

1.2 SingleThreadExecutor使用样例

  1. 单线程化线程池SingleThreadExecutor特点:
    • 只有一个核心线程(保证所有任务按照指定顺序在一个线程中执行,不需要处理线程同步的问题)。
    • 应用场景:不适合并发但可能引起IO阻塞性及影响UI线程响应的操作,如数据库操作,文件操作等。
  2. SingleThreadExecutor的意义:
    • 缓存线程、进行池化,可实现线程重复利用、避免重复创建和销毁所带来的性能开销。
    • 当线程调度任务出现异常时,会重新创建一个线程替代掉发生异常的线程。
    • 任务执行按照规定的调度规则执行。线程池通过队列形式来接收任务。再通过空闲线程来逐一取出进行任务调度。即线程池可以控制任务调度的执行顺序。
    • 可制定拒绝策略。即任务队列已满时,后来任务的拒绝处理规则。
package com.yuanxw.chapter21;

import java.util.Random;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
import java.util.stream.IntStream;

public class ScheduledThreadPoolExample {
    // 随机数:使用long参数的所有64位作为因子值。
    private static Random random = new Random(System.currentTimeMillis());

    public static void main(String[] args) {
        // 使用Executors创建单个worker线程的Executor
        ExecutorService executorService = Executors.newSingleThreadExecutor();
        // 始终只有一个线程,执行ScheduledThreadPoolExample#processTask方法
        IntStream.range(1, 10).forEach(i -> executorService.execute(ScheduledThreadPoolExample::processTask));
        // corePoolSize 和 maximumPoolSize都是:1,因此应用程序不会结束,需要调用executorService.shutdown()方法,关闭线程池。
        executorService.shutdown();
    }

    /**
     * 线程休眠的方法
     */
    private static void processTask() {
        try {
            long start = System.currentTimeMillis();
            TimeUnit.SECONDS.sleep(random.nextInt(5));
            long end = System.currentTimeMillis();
            System.out.println(String.format("【%s】线程执行结束,耗时【%s】秒>>>>>>>>>>>", Thread.currentThread().getName(),((end - start)/1000)));
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

执行结果:

【pool-1-thread-1】线程执行结束,耗时【1】秒>>>>>>>>>>>
【pool-1-thread-1】线程执行结束,耗时【2】秒>>>>>>>>>>>
【pool-1-thread-1】线程执行结束,耗时【4】秒>>>>>>>>>>>
【pool-1-thread-1】线程执行结束,耗时【2】秒>>>>>>>>>>>
【pool-1-thread-1】线程执行结束,耗时【3】秒>>>>>>>>>>>
【pool-1-thread-1】线程执行结束,耗时【1】秒>>>>>>>>>>>
【pool-1-thread-1】线程执行结束,耗时【1】秒>>>>>>>>>>>
【pool-1-thread-1】线程执行结束,耗时【4】秒>>>>>>>>>>>
【pool-1-thread-1】线程执行结束,耗时【3】秒>>>>>>>>>>>

在这里插入图片描述
SingleThreadExecutor 的 execute()方法的执行示意图(该图片来源:《Java 并发编程的艺术》):

  1. 如果当前运行的线程数少于 corePoolSize,则创建一个新的线程执行任务;
  2. 当前线程池中有一个运行的线程后,将任务加入 LinkedBlockingQueue
  3. 线程执行完当前的任务后,会在循环中反复从 LinkedBlockingQueue 中获取任务来执行;

    – 以上为《JAVA多线程(二十一)Java多线程之SingleThreadExecutor单线程化线程池》,如有不当之处请指出,我后续逐步完善更正,大家共同提高。谢谢大家对我的关注。

——厚积薄发(yuanxw)

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JAVA多线程(二十一)Java多线程之SingleThreadExecutor单线程化线程池 的相关文章

  • np.maximum()函数详解——将数组中小于某值的数用0代替

    目标 xff1a 把数组中小于某个值的数都设为0 np max a axis 61 None out 61 None keepdims 61 False 求a中的最大值 np maximum xff1a a b out 61 自定义 a 与
  • python-opencv 使用LBP特征检测人脸

    概述 最近在做人脸检测相关功能 xff0c 目前注意到比较传统 xff08 非深度 xff09 人脸检测特征包括harr和LBP HOG用于行人检测更多些 xff0c opencv包括了这两种特征算法 xff0c 并且相对来说 xff0c
  • 机器视觉特征提取介绍:HOG、SIFT、SURF、ORB、LBP、HAAR

    一 概述 这里主要记录自己的一些感悟 xff0c 不是很系统 想要详细系统的理论 xff0c 请参考文末的 图像处理之特征提取 个人不是专业cv工程师 xff0c 很多细节没有深究 xff0c 描述可能不严谨 在总结物体检测算法之前先把基础
  • win7 wifi 无Internet访问权限或者有限的访问权限

    自己家的无线路由器 xff0c 手机和笔记本都使用正常 xff0c 但是一台新笔记本连上之后总是提示 有限的访问权限 xff0c 无法连公网 网上的很多办法都不管用 xff0c 什么设置静态IP或者重启路由 xff0c 基本都是瞎扯 好在一
  • springboot 本地调试没问题,打包运行报错原因

    1 如果引用了本地jar包或者so库 xff0c dll库等文件 xff0c 需要在打包的时候都加载进去 如下图 xff1a 本地正常 xff0c 打包的时候谨记 xff0c 需要打包进去 xff0c 怎么验证是否打包成功呢 xff1f 我
  • CMakeList学习笔记

    hello cpp为源文件 构建一个CMakeLists txt cmake minimum required VERSION 2 8 project hello add executable hello hello cpp 在目录中的bu
  • C语言--iota函数

    一 iota函数 xff1a 功能 把一个整数转换为字符串 eg include lt stdlib h gt include lt stdio h gt void main int number 61 43 char string 100
  • STM32F103ZET6和STM32F103C8T6编程不一样吗?

    我把C C 43 43 选项卡中 STM32F10X HD USE STDPERIPH DRIVER 修改为 STM32F10X MD USE STDPERIPH DRIVER 编译成功 谢谢O O 初始化的时候要调用SystemInit
  • STM32F103ZET6和STM32F103C8T6芯片的区别

    是这样的 xff0c 一个具体的STM32F103系列芯片的内存有多大 xff0c 你看一下芯片上的型号就行了 STM32F103XY 注意 xff0c XY是个代号 xff0c X是表示封装有多少个引脚 xff0c 比如 xff0c 如果
  • Keil(MDK-ARM)使用教程——在线调试

    Keil xff08 MDK ARM xff09 使用教程 xff08 三 xff09 在线调试 由于我是直接使用 xff08 打开现有的软件工程 xff09 xff0c 如果跟着需要下载上面演示参考的软件工程 才行 工程默认是使用硬件在线
  • ch340是什么芯片

    CH340 是一个USB 总线的转接芯片 xff0c 实现USB 转串口 USB 转IrDA 红外或者USB 转打印口 在串口方式下 xff0c CH340 提供常用的MODEM联络信号 xff0c 用于为计算机扩展异步串口 xff0c 或
  • Ubuntu16的详细安装教程

    有一点很重要要说一下 xff0c 每个人学习Linux的动机都不一样 xff0c 而这个动机会决定你对Linux的态度 xff0c 如果你仅仅是想尝鲜 xff0c 装个笔什么的 xff0c 不当作自己的职业方向去学习Linux的 劝这类人还
  • 是否能在keil中混合编译c和c++程序

    keil中支持混合编译C和C 43 43 程序 xff0c 因为其本质最终都是编译成汇编 xff0c 所以是可以同时操作的 在混合编译时 xff0c 需要注意以下几点 xff1a 1 C文件扩展名必须为 C xff0c C 43 43 文件
  • ds18b20工作原理和测温原理介绍

    DS18B20是美国DALLAS半导体公司继DS1820之后最新推出的一种改进型智能温度传感器 与传统的热敏电阻相比 xff0c 他能够直接读出被测温度并且可根据实际要求通过简单的编程实现9 xff5e 12位的数字值读数方式 可以分别在9
  • 如何将.hex文件转化为.c文件

    说明楼主太初级 xff0c 迷恋于C 1 C与HEX并不是一一映射的 xff0c 有可能N个人写的C xff0c 会出同一个HEX xff0c 你希望回成哪个人写的呢 xff1f 或许你可能说 xff1a 任意一个孝可以 xff0c 只要能
  • 嵌入式linux 和 用stm32进行的嵌入式开发 这两者之间有什么关联性吗?

    作者 xff1a 知乎用户 链接 xff1a https www zhihu com question 53880054 answer 164501004 来源 xff1a 知乎 著作权归作者所有 商业转载请联系作者获得授权 xff0c 非
  • #if 0 ... #endif的真实用途

    在过去都没有去理会 if 的作用 xff0c 今天突发奇想 xff0c 开启编译器试一试 很多人都知道 if 0 endfif的作用跟 的作用是一样的 xff0c 就是注释 xff0c 可是注释为什么不用注释符号 就行了么 xff1f go
  • .hex文件和.bin文件区别

    HEX文件和BIN文件是我们经常碰到的2种文件格式 因为自己也是新手 xff0c 所以一直对这两个文件懵懵懂懂 xff0c 不甚了解 xff0c 最近在做STM32单片机的IAP更新 xff0c 其中要考虑HEX文件和BIN文件 xff0c
  • EEPROM和flash的区别

    From https blog csdn net yuanlulu article details 6163106 EEPROM的全称是 电可擦除可编程只读存储器 xff0c 即Electrically Erasable Programma
  • 264 nal type

    NUAL HEAD 43 43 0 1 2 3 4 5 6 7 43 43 43 43 43 43 43 43 43 F NRI Type 43 43 F xff1d Forbidden zero bit 61 0 NRI 61 Nal r

随机推荐

  • SubClassWindow详解

    许多Windows程序员都是跳过SDK直接进行RAD开发工具 或VC xff0c 我想VC应不属于RAD 的学习 xff0c 有些人可能对子类化机制比较陌生 我们先看看什么是Windows的子类化 Windows给我们或是说给它自己定义了许
  • stl upper_bound函数实现

    写了一个upper bound的实现 其中递归使用二分法求解最上界 xff0c 虽然写的完全不像STL的风格 xff0c 但是练手还是可以的 view plaincopy to clipboardprint 01 include lt io
  • 云原生 - 2、Openstack架构

    云原生 2 Openstack架构 1 什么是Openstack2 Release3 核心架构4 官方入口5 核心组件6 相关文章导读 1 什么是Openstack OpenStack是一个开源的云计算管理平台项目 xff0c 由NASA
  • 关于TrackMouseEvent用法总结

    对于这个函数我也是最近想研究控件自绘才知道它真正怎么用 以前只是见到过 嗯 废话不多说 我先说下我的问题 如何响应鼠标离开某个窗体 控件 事件 先大概讲下步骤 然后再集中对 TrackMouseEvent 进行详解 为按钮添加以下几个函数
  • 关于CComboBox的自绘

    我想 如果大家学过一些控件的自绘的话 CComboBox算是很难的一种了 首先是它本身的复杂度 它由三个控件组成 CEdit CListBox CButton 我想但就CEdit来讲 就够你受得了 还要想想他们之间的消息传递 不禁让人无从下
  • 2011年总结

    又是一年年终时 亦是一年总结时 想想自己从去年写年终总结到现在 已经很久没有写过字了 时间过得真快 又是一年过去了 这一年也是我出来工作的第二年 这一年总体来说自己无论在技术还是心态方面有了很大的进步 记得刚出学校那会 啥都不知道 对于工作
  • 内部链接与外部链接

    在说内部连接与外部连接前 xff0c 先说明一些概念 1 声明 一个声明将一个名称引入一个作用域 在c 43 43 中 xff0c 在一个作用域中重复一个声明是合法的 以下都是声明 xff1a int foo int int 函数前置声明
  • partition/stable_partition详解

    Partition 将满足条件的元素向前移动 TEMPLATE FUNCTION partition template lt class BidIt class Pr gt inline BidIt Partition BidIt Firs
  • jsoncpp解析拼装数组

    int main 数组创建与分析 例子一 string strValue 61 34 34 ldh 34 34 001 34 34 gfc 34 34 002 34 34 yyj 34 34 003 34 34 andy 34 34 005
  • 查看静态库(.lib)和动态库(.dll)的导出函数的信息

    一般情况下 xff0c 我们需要查看一个DLL或EXE中的包含的函数或是依赖的函数之类的信息 xff0c 可以使用VS自带的工具dumpbin xff1b 可以直接在命令行下输入dumpbin就可以查看他的使用说明 xff0c 如果未显示
  • do {...} while (0) 在宏定义中的作用

    http www cnblogs com lanxuezaipiao p 3535674 html 如果你是一名C程序员 xff0c 你肯定很熟悉宏 xff0c 它们非常强大 xff0c 如果正确使用可以让你的工作事半功倍 然而 xff0c
  • 即插即用型设备驱动的加载过程

    现假设驱动程序已被正确安装 xff1a 1 某种PnP总线驱动发现了即插即用设备的存在 xff1a 对于热插拔设备 xff0c 则发现过程发生于插入设备的瞬间 xff1b 如果是非热插拔设备 xff0c 则发现过程发生于系统启动时 2 Pn
  • C++如何编写属于自己的头文件 ---- 自己动手,丰衣足食

    自己动手 xff0c 丰衣足食 ps 其实这一篇文章老早以前就写了 xff0c 一直扔在草稿箱 xff0c 今天想起来了然后就发了出来 首先 xff0c 熟悉熟悉这些 是的没错 xff0c 这就是我们的Dev cpp 忽略其他东西 xff0
  • ubuntu安装vnc server-x11vnc并设置开机自动启动

    ubuntu安装x11vnc并设置开机自动启动 安装x11vnc 打开终端 xff0c 使用如下命令x11vnc span class hljs built in sudo span apt get install x11vnc 手动连接
  • 笔记本安装ubuntu18.04步骤及分区方法

    家中闲置一台08年的笔记本 xff08 没有无线无卡 xff09 xff0c 自己加装了一个2G的内存条 xff0c 食之无味弃之可惜 xff0c 思量再三准备重装Ubuntu18 04的系统当做小型服务器使用 因此记录下安装步骤以及分区方
  • 滑模控制学习笔记(三)

    滑模控制学习笔记 xff08 三 xff09 基于趋近律的滑模控制几种典型的趋近律等速趋近律指数趋近律幂次趋近律一般趋近律 基于趋近律的控制器设计仿真实例状态空间模型建立滑模控制器模型建立仿真结果 基于趋近律的滑模鲁棒控制仿真实例 基于趋近
  • 滑模控制学习笔记(六)

    滑模控制学习笔记 xff08 六 xff09 等效滑模控制等效滑模控制器设计等效控制设计滑模控制设计 仿真实例 等效滑模控制 滑模控制率可由等效控制 u e q u eq
  • 文件描述符 和 流的关系

    任何一种操作系统中 xff0c 程序在开始读写一个文件的内容之前 xff0c 必须首先在程序与文件之间建立连接或通信通道 xff0c 这一过程称为打开文件 打开一个文件的目的可以是为了读或者为了写 xff0c 也可以是即读又写 UNIX系统
  • 试用了5款BI分析工具,终于找到了上手最快的那一个!

    前几天 xff0c 领导甩给我一个任务 xff0c 考察几个BI工具 xff0c 下季度立项用 潜心做ETL的我 xff0c 对BI只是略懂 之前上的BO xff0c 由于开发模式不适应 人员用不惯 xff0c 再加上负责这块的同事走的走
  • JAVA多线程(二十一)Java多线程之SingleThreadExecutor单线程化线程池

    1 JAVA多线程 二十一 Java多线程之SingleThreadExecutor单线程化线程池 1 1 单线程化线程池SingleThreadExecutor SingleThreadExecutor 是只有一个线程的线程池 通过源代码