通过SingleThreadExecutor源码窥探面向对象设计模式

Hodgkin-Huxley Model 介绍了经典的动力学模型:HH Model 阅读详情

本文4300+字,实际文字大概300,建议阅读时间10分钟

我们知道Java预留了四种多线程池

其中一种为SingleThreadExecutor,如同其字面意思就是单线程池,看一下源码:
源码来自Executors类中静态方法

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

为了体现设计模式,我们再给出另一个线程池FixedThreadPool的源码

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

发现所有的预留多线程池只不过就是对不同参数的饿ThreadPoolExecutor的处理,值得提一下,如果你对ThreadPoolExecutor不熟悉的话,我贴出源码

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory,
                              RejectedExecutionHandler handler)
     

省略构造方法体内容,只介绍两个参数:
corePoolSize 核心线程池大小
maximumPoolSize 最大线程池大小

我们希望刚才的newSingleThreadExecutor是单线程,其中corePoolSize = maximumPoolSize = 1 。

问题来了:如何设计保证线程池在运行中 corePoolSize和maximumPoolSize不变?

如果像FixedThreadPool那样设计会带来一个什么风险?

即直接返回一个ThreadPoolExecutor对象,用Service接口类接收的方式

如下图的继承关系可以直接通过强制类型转换,把ThreadPoolExecutor强制转换为ThreadPoolExecutor对象,通过set方法改变该值。
ThreadPoolExecutor的层次关系
在这里插入图片描述

封装一个新的类FinalizableDelegatedExecutorService

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

给出FinalizableDelegatedExecutorService源码:

static class FinalizableDelegatedExecutorService
        extends DelegatedExecutorService {
        FinalizableDelegatedExecutorService(ExecutorService executor) {
            super(executor);
        }
        protected void finalize() {
            super.shutdown();
        }
    }

可以看出该内部类继承于DelegatedExecutorService,那么继续给出DelegatedExecutorService源码

static class DelegatedExecutorService extends AbstractExecutorService {
        private final ExecutorService e;
        DelegatedExecutorService(ExecutorService executor) { e = executor; }
        public void execute(Runnable command) { e.execute(command); }
        public void shutdown() { e.shutdown(); }
        public List<Runnable> shutdownNow() { return e.shutdownNow(); }
        public boolean isShutdown() { return e.isShutdown(); }
        public boolean isTerminated() { return e.isTerminated(); }
        public boolean awaitTermination(long timeout, TimeUnit unit)
            throws InterruptedException {
            return e.awaitTermination(timeout, unit);
        }
        public Future<?> submit(Runnable task) {
            return e.submit(task);
        }
        public <T> Future<T> submit(Callable<T> task) {
            return e.submit(task);
        }
        public <T> Future<T> submit(Runnable task, T result) {
            return e.submit(task, result);
        }
        public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks)
            throws InterruptedException {
            return e.invokeAll(tasks);
        }
        public <T> List<Future<T>> invokeAll(Collection<? extends Callable<T>> tasks,
                                             long timeout, TimeUnit unit)
            throws InterruptedException {
            return e.invokeAll(tasks, timeout, unit);
        }
        public <T> T invokeAny(Collection<? extends Callable<T>> tasks)
            throws InterruptedException, ExecutionException {
            return e.invokeAny(tasks);
        }
        public <T> T invokeAny(Collection<? extends Callable<T>> tasks,
                               long timeout, TimeUnit unit)
            throws InterruptedException, ExecutionException, TimeoutException {
            return e.invokeAny(tasks, timeout, unit);
        }
    }

不要被这种代码吓到,看构造器:

DelegatedExecutorService(ExecutorService executor) { e = executor; }

把子类ThreadPoolExecutor隐式转为父类对象ExecutorService,在封装给成员变量e, 其中所有方法通过e来调用.并把e 私有,取消private方法,且DelegatedExecutorService和ThreadPoolExecutor无继承关系,仅都实现了接口ExecutorService,这样就消除了强制类型转换的可能。彻底的把ThreadPoolExecutor隐藏起来,这就是封装的体现
在这里插入图片描述

这种方法实现的原理

把SingleThreadExecutor(ThreadPoolExecutor的对象)封装在了一个FinalizableDelegatedExecutorService对象中,FinalizableDelegatedExecutorService父类DelegatedExecutorService包含有一个ExecutorService(接口)e对象, 而其本身也是ExecutorService(接口)对象,并且其实现了部分ThreadPoolExecutor功能(调用e对象),此外,去掉了set 和get 把e隐藏,无法改变e

这种方法既然不是相同子类,如何对上层无痛(没有感觉)?

都实现了ExecutorService接口,此外所有多线程池的返回都是ExecutorService接口对象。
多态性的体现

Windows 10下用VS2022编译AFSIM 2.9.0的完整避坑指南 本文提供了在Windows 10系统下,使用Visual Studio 2022编译AFSIM 2.9.0仿真框架的详细指南。文章系统梳理了从环境准备、CMake配置、编译链接到安装打包的全流程,并重点针对编译过程中常见的文件编码、命名空间冲突等高频错误提供了具体解决方案,旨在帮助开发者高效避坑,顺利完成AFSIM在Windows平台上的构建。 阅读详情

相关推荐

Mac上除了Homebrew,这几种安装ADB的方法你可能也需要知道(含手动配置避坑)

本文全面解析Mac上五种ADB安装方案,从Homebrew到手动配置,涵盖常见问题解决与环境变量配置。特别针对macOS High Sierra等老旧系统提供专属解法,帮助开发者高效安装Android Debug Bridge(ADB),避免常见陷阱,提升开发效率。

weixin_42546392的博客 323

JUC线程池——newSingleThreadExecutor源码解析&&JDK提供线程池ThreadPoolExecutor执行任务流程解析

初始化的线程池中只有一个线程,如果该线程异常结束,会重新创建一个新的线程继续执行任务,唯一的线程可以保证所提交任务的顺序执行; 由于使用了无界队列, 所以SingleThreadPool永远不会拒绝, 即饱和策略失效; 本文对newSingleThreadExecutor执行流程结合源码进行详细的分析,让读者更加了解并发下newSingleThreadExecutor的执行流程,以及FutureTask的实现

小爽帅到拖网速的博客 887

变压器耦合放大器(低频应用+高频应用)

变压器耦合放大器(低频应用+高频应用)

m0_54943120的博客 2275

揭秘newSingleThreadExecutor:深度解析与源码探秘

newSingleThreadExecutor是Java线程池框架中的一个重要组件,它通过维护一个单一的工作线程来执行任务,保证了任务的顺序执行。它的实现基于ThreadPoolExecutor类,并通过设置特定的参数来实现其独特的功能。对于需要保证任务顺序执行的场景,newSingleThreadExecutor是一个非常好的选择。

m0_51176516的博客 1284

[TC3XX]AURIX TC3XX系列之启动流程

本文介绍了微控制器(MCU)启动过程中固件(Firmware)和启动软件(SSW)的工作原理。MCU上电复位后,硬件完成初始化,BootROM中的固件开始执行,进行参数加载、模式选择等操作。SSW作为第一个执行的软件,负责时钟配置、安全检查、多核管理及启动模式选择,最终跳转至用户代码。启动模式包括内部Flash启动、Bootloader模式(通过ASC或CAN接口)和备用启动模式(ABM),具体由复位类型、引脚配置和UCB设置决定。文章特别指出英飞凌TC3xx系列芯片中固件不可修改,只能通过配置参数定制启动

redparrot2008的博客 1423

MATLAB机械臂轨迹规划:在关节空间中生成多项式轨迹以及 jtraj函数(内容超详细讲解)

matlab机器人仿真,关节空间多项式轨迹生成

qq_40969179的博客 1万+

SingleThreadExecutor详解

SingleThreadExecutor是使用单个worker线程的Executor。下面是SingleThreadExecutor的源代码实现。 public static ExecutorService newSingleThreadExecutor() { return new FinalizableDelegatedExecutorService (new ThreadPoolExecut...

YK的博客 5650

C#操作MySQL从入门到精通(1)——安装MySQL数据库

我们使用C#操作MySQL数据库第一步要做的就是安装MySQL数据库,本文就是详细讲解如何安装MySQL数据库。

qq_34059233的博客 965

Java 线程池之SingleThreadExecutor

是 Java 并发包()中的一种线程池实现。它内部只有一个工作线程,所有提交的任务将按照提交的顺序依次执行。确保任务不会并发执行,因此非常适用于需要按顺序执行任务的场景。

yimeixiaolangzai的博客 1295

【机器人技术基础】MATLAB Robotics Toolbox PUMA560 运动学正逆解

机器人技术基础实验2报告 1. 实验目的和要求 2. 实验手段 2.1 实验原理 2.2 函数详解 3. 实验主要内容 4. 实验结果和分析 4.1 正运动学求解 例1 例2 4.2 逆运动学求解 例1 例2 1. 实验目的和要求 掌握常见形式的机器人的D-H坐标系建立方法、运动学建模; 正逆运动学分析与求解; 使用Robotics Toolbox对直角坐标机器人、圆柱坐标机器人、球坐标机器人、PUMA560其中之一建立运动学模型,正逆求解和仿真。 2. 实验手段 2.1

【人工智障 | 计算鸡视觉 | 机器孩】 1万+

Vue - 详细实现低代码平台,支持拖曳式可视化生成应用软件功能,用户通过拖拽元素、搭积木的方式创建应用(适合迭代的基础架构、低代码平台)

Vue低代码平台-拖曳式拖拉拽可视化生成应用软件,拖拽式低代码数据可视化开发平台,vue实现拖拽,拖拽式Vue组件代码生成平台,基于vue的可视化拖拽代码生成工具,Vue实现可拖拽组件的方法,一个低代码平台的前端部分,靠拖拉拽生成页面。Vue技术栈从零实现低代码可视化搭建平台示例,低代码轮子,通过拖拽就可生成Vue代码的平台来了,vue低代码平台开发相关比低代码更强大的零代码开发平台,这款低代码SAAS数据可视化工具,拖拽生成大屏。vue实现拖拽效果,Vue自由拖拽缩放组件,自定义组件(文本、图片

🏆 前端领域优质创作者 1万+

SingleThreadExecutor的使用简析

SingleThreadExecutor作用 简单一句话概括,就是创建一个单线程的线程池。 示例代码 public class TestMain { //格式化 static SimpleDateFormat sim = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); //AtomicInteger用来计数 stat...

硅脂味咖啡的博客 2682

【3D Slicer】的小白入门使用指南一

3D Slicer 是一个免费的开源软件平台,用于医学、生物医学和其他 3D 图像的可视化、处理、分割、配准和分析。Slicer 的功能包括:读/写。

图挖掘领域,新晋砖家 ☞ 未来可期,欢迎和静静一起学习交流吖 5559

java线程池:为什么会有SingleThreadExecutor线程池?

如果当前线程意外终止,线程池会创建一个新的线程来代替它,保证线程的可用性。它提供了一种简单有效的方式来管理和执行单线程任务,避免了多线程带来的复杂性和潜在的线程安全问题。这对于某些需要保持顺序性的任务非常有用,例如需要按照请求的顺序处理的任务队列。适用于长时间任务:由于只有一个线程,可以避免频繁的线程切换开销,因此适用于长时间运行的任务,可以减少上下文切换带来的性能损失。线程安全:由于只有一个线程执行任务,不会存在并发访问共享资源的问题,因此不需要考虑线程安全性,可以避免使用锁或其他同步机制。

学亮编程手记 449

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

LinePhone3.2.7(android端最新版本) sip客户端

SIP客户端For android:LinePhone3.2.7(最新版本),官网地址:http://www.linphone.org/

单线程线程池 newSingleThreadExecutor

【代码】单线程线程池 newSingleThreadExecutor。

张紫娃的博客 3408

廖雪峰Python教程[完整版]

廖雪峰的python教程整理的,已经排好版了,而且还是完整的,适合小白

线程池问题

线程池问题

lgnorantpony的博客 1087

Devexpress16.2.6破解工具

Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具Devexpress16.2.6破解工具

【Java基础-49.3】Java中的SingleThreadExecutor:使用、原理与应用场景

是Java中接口的一种实现,它使用单个工作线程来执行任务。与其它线程池不同,保证所有任务按照提交的顺序依次执行,因此它非常适合需要顺序执行任务的场景。是Java中一种简单但非常有用的线程池实现。它通过单个工作线程顺序执行任务,适用于需要顺序执行、单线程调度或任务依赖的场景。然而,在使用时需要注意无界队列可能带来的内存风险,并确保任务中的异常得到妥善处理。通过合理使用,我们可以简化多线程编程的复杂性,提高代码的可维护性和可靠性。

weixin_39033358的博客 1225

多线程(二) | 彻底搞懂线程池-Executors

[原文约7000字] 上篇文章,我们讲解了通过Thread和 Runnable 使用线程的方法,并且演示了如何创建一个线程并启动,今天我们来聊一聊多线程中的线程池。 一、为什么要使用线程池 我们使用多线程的一个一般步骤是: 先创建一个线程,然后线程执行线程任务,线程任务执行完毕后,线程会被销毁。 但是线程的创建和销毁是比较耗费资源的。在高并发场景之下,如果需要开启大量的线程,而每个线程它执行任务所需的时间很短的情况下,那么线程的频繁的创建和销毁就会成为性能的瓶颈。所以线程池应运而生。线程池的主要功能

lsqingfeng的博客 4168

JAVA 线程池SingleThreadExecutor实践教程

是一个单线程的Executor,它使用单个工作线程来执行任务,保证所有任务按照指定顺序(FIFO, LIFO, 优先级)执行。下面是使用。

guanglihuan的专栏 1376

Java多并发(七)| Executor框架(四种线程池详解)

FixedThreadPool:SingleThreadExecutor:CachedThreadPool:ScheduledThreadPoolExecutor:SingleThreadScheduledExecutor: 概述 流程图 如果使用无界队列作为工作队列的影响,队列容量是MAX 2.2 SingleThreadExecutor详解 代码 概述 流程图 2.3 CachedThreadPool详解 代码 概述 流程图 Synchronou

光看不点赞的博客 1719

【学习】线程池:线程池提交任务的方式execute与submit的区别

【学习】线程池:线程池提交任务的方式execute与submit的区别

u010328311的博客 770

Java中的线程池(3)----SingleThreadExecutor

SingleThreadExecutor

TimeTDIT的博客 6万+

Spring中的几种线程池使用总结

每个工作线程在处理自己的工作队列同时,会尝试窃取一个任务(或是来自于刚刚提交到 pool 的任务,或是来自于其他工作线程的工作队列),窃取的任务位于其他线程的工作队列的队首,也就是说工作线程在窃取其他工作线程的任务时,使用的是 FIFO 方式。第二种,装饰线程池,其原理也是实现的第一种,只不过他的好处是更便捷,尤其对线程的监听,随时随地可以监听此线程任务的内部状态,做出相应的处理。第一种,属于Spring自带,传统的jdk封装实现,对线程的异步执行后的结果,需要自己实现监听或者阻塞,相对麻烦。

m0_69804655的博客 2381

1.2 SingleThreadExecutor

线程池工具类给我们提供了一些常见的线程池,这片来谈一谈SingleThreadExecutor线程池 使用方式 创建方式比较简单,直接使用工具创建就ok,Executors.newSingleThreadExecutor() 源码 /** * Creates an Executor that uses a single worker thread operating * off an unbounded queue. (Note however that if this single

不停的奔跑 653

SingleThreadExecutor 用和不用的区别

SingleThreadExecutor 存在的意义

Aichuiniu666的博客 786

一文搞懂 java 线程池:SingleThreadExecutor 和 CachedThreadPool 原理

本文详细介绍了 Java 中的 SingleThreadExecutor 和 CachedThreadPool 两种线程池。SingleThreadExecutor 是一个只有单一工作线程的线程池,适合顺序执行任务,能够有效处理需要顺序执行的一系列任务,并保持任务之间的顺序性。它提供了线程生命周期管理、顺序执行、线程鲁棒性、易于调试和任务队列管理等功能。而 CachedThreadPool 是一个会根据需要创建新线程的线程池,适合处理短生命周期的异步任务,能够动态调整线程数量以应对任务量的变化。它使用 Sy

shengjk1的博客 1591
上一篇: Mybatis框架下Sql语句在java代码中查询不到结果
SpringQAQ
博客等级 码龄8年 3粉丝 10原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值