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

2023-05-16

本文简单介绍Java中的另一种线程池----SingleThreadExecutor。

创建SingleThreadExecutor的静态方法

首先还是先看一下创建SingleThreadExecutor的Executors下的静态方法:

    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();
        }
    }
可以看到FinalizableDelegatedExecutorService这个类实际上继承了DelegatedExecutorService,然后加了个finalize方法保证线程池的关闭。那么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);
        }
    }
实际上就是对ExecutorService类进行了一个包装,相当于设计模式中的装饰者模式,防止暴露出一些不应该暴露的方法。


说到这里应该很明了了,实际上FinalizableDelegatedExecutorService这个类就是对ExecutorService进行了一个包装,防止暴露出不该被暴露的方法,然后加上了finalize方法保证线程池的关闭。

现在回头看newSingleThreadExecutor这个静态方法,根据其调用的ExecutorService构造函数的构造参数,可以了解到:

1、这种线程池的核心线程池大小为1,线程池最多线程数量也为1,因此keepAliveTime实际上也就没有意义了;

2、这种线程池的阻塞队列为LinkedBlockingQueue<Runnable>类型的,LinkedBlockingQueue在上一篇文章说过了,是一种最大容量为Integer.MAX_VALUE的,放入锁和取出锁不一样的一种阻塞队列。


那么问题来了,newSingleThreadExecutor()和newFixedThreadPool(1)有什么区别呢?

上面说了那么多,答案应该也很显而易见了,实际上差别仅仅在于newSingleThreadExecutor()返回的线程池少暴露了一些方法并且多了个finalize方法保证线程池调用shutdown(),仅此而已

网上有一些错误的回答,比如说前者线程执行期间抛出异常仍然能保证又其他线程顶替他,而后者不行,这样的回答都是错的。想要论证这是错的实际上很简单,对newFixedThreadPool(1)进行测试:

package newFixedThreadPool;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test {
    public static void main(String[] args) {
        ExecutorService fixedThreadPool = Executors.newFixedThreadPool(1);
        int i = 0;
        while (i++<10) {
            final int index = i;
            fixedThreadPool.execute(new Runnable() {
                @Override
                public void run() {
                    if(index == 1){
                        throw new IllegalStateException("handler exception");//线程运行时抛出异常
                    }
                    System.out.println(Thread.currentThread().getName() + "执行");
                    try {
                        Thread.sleep(3000);//模拟当前线程执行其他操作 花费3s
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
        }
        fixedThreadPool.shutdown();
    }
}
运行结果如下:


可以看到对于newFixedThreadPool(1),当一个线程在运行时抛出异常也会有其他线程顶替他去完成接下来的任务。

接下来对newSingleThreadExecutor()方法进行测试:

package newSingleThreadExecutor;

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class Test {
    public static void main(String[] args) {
        ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
        int i = 0;
        while (i++ < 10) {
            final int index = i;
            singleThreadExecutor.execute(new Runnable() {
                @Override
                public void run() {
                    if(index == 1){
                        throw new IllegalStateException("handler exception");
                    }
                    System.out.println(Thread.currentThread().getName() + "执行" + "No." + index);
                }
            });
        }
        singleThreadExecutor.shutdown();
    }
}


执行结果如下:


对于newSingleThreadExecutor()来说,也是当线程运行时抛出异常的时候会有新的线程加入线程池替他完成接下来的任务。


以上为自己的一些认识 如果有错误请指出

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

Java中的线程池(3)----SingleThreadExecutor 的相关文章

  • 声纳违规:安全性 - 使用 byte[] 时直接存储数组

    我确实遇到过以下两篇关于类似问题的帖子声纳违规 https stackoverflow com questions 11580948 sonar violation security array is stored directly and
  • 匿名内部类显示不正确的修饰符

    据我了解 以下代码应该打印true作为输出 但是 当我运行这段代码时 它正在打印false 来自 Java 文档15 9 5 匿名类 https docs oracle com javase specs jls se8 html jls 1
  • 无法从 TemporalAccessor 获取 OffsetDateTime

    当我这样做时 String datum 20130419233512 DateTimeFormatter formatter DateTimeFormatter ofPattern yyyyMMddHHmmss withZone ZoneI
  • 包含小时、分钟和秒的周期[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 我需要一个代表年 月 周 日 小时 分钟 秒的间隔数据类型 前三年 年 月 日 可以用Period最后
  • RSA 加密-解密:BadPaddingException:数据必须以零开头

    对于一个被问了很多次的问题 我很抱歉向您询问您的技能 我有一个关于 RSA 加密的问题 我已经检查过有关此问题的其他主题 但没有找到任何有用的答案 我希望你能帮助我 我想读取一个文件 加密其内容 然后解密它并将这些解密的字节放入一个新文件中
  • Selenium - 保存网站,包括所有图像、css、dom

    我想使用 firefox 或 chrome 访问带有 selenium 的页面 当页面加载时 我想从页面下载所有图像 css dom 我想存储每张图像 就像我在其中找到它们一样 chrome gt Tools gt Development
  • 如何在 Java 中安装附加包?

    我对 Java 很陌生 我想使用名为的包中的一些功能daj 教程代码有以下几行 import daj import java util import java lang Math import Msg 但第一行和第四行会产生红色下划线 导致
  • 从继承的受保护 Java 字段创建公共访问器

    我怎样才能完成以下工作 class Foo extends javax swing undo UndoManager increase visibility works for method override def editToBeUnd
  • 可以混合使用 JVM 语言吗?即:Groovy 和 Clojure

    我知道你可以轻松地混合groovy java clojure java 无论什么JvmLang java 这是否也意味着我也可以让 clojure 和 groovy 代码进行交互 如果我使用 Grails 或 jRoR 我也可以在该环境中使
  • 如何将 wsdl 内部架构设置为 Jaxb2Marshaller 以验证我所做的每篇文章?

    我正在使用 SOAP Web 服务 在调用它之前我必须验证每个 xml 帖子 所以我正在使用 The CXF codegen 插件生成POJO树结构 第三部分 wsdl xxxx soap service wsdl 一个类实现Web服务网关
  • Keycloak 社交登录 REST API

    我已经为我的 keycloak 实例启用了谷歌社交登录 但我需要将其用作休息服务 是否有可用于执行此操作的端点 Keycloak 中没有 Google 身份验证 API 但您可以使用以下方法解决它代币交换 https www keycloa
  • 获取证书链

    我正在 Java 中使用 X509 证书 给定一个证书 是否可以在签名层次结构中找到所有其他证书 直到找到根证书 我有一个证书文件 带有 cer扩展名 我想提取父签名证书 我想继续查找该证书的父证书 直到获得最终的自签名根证书 我已经检查了
  • EclipseLink 2.7.0 和 JPA API 2.2.0 - 签名不匹配

    当运行由maven构建的具有以下依赖项的项目时
  • WebSocketStompClient 将无法连接到 SockJS 端点

    我正在尝试新的 从版本 4 2 开始 java STOMP 客户端支持 我的出发点是入门指南 使用 WebSocket 构建交互式 Web 应用程序 http spring io guides gs messaging stomp webs
  • 有时 Properties.load() 会跳过行

    在以下情况下 Properties load 会跳过 InputStream 的第二行 这是 Java 的错误还是正常行为 public class PropTest public static void main String args
  • 相当于 C# 中 Java 的“ByteBuffer.putType()”

    我正在尝试通过从 Java 移植代码来格式化 C 中的字节数组 在 Java 中 使用方法 buf putInt value buf putShort buf putDouble 等等 但我不知道如何将其移植到 C 我尝试过 MemoryS
  • Android应用程序中的模式输入

    我想知道是否有其他替代方案可以替代 Android 上平庸的 EditText 密码输入 是否有 API 或开源代码可以集成到我的应用程序中 类似于锁屏图案解锁 Intent 可能会返回哈希值 数字 字符串或代表用户输入的模式的任何内容 我
  • 根据 Java 环境变量中的值创建使用 @JsonIgnore 的自定义注释

    我需要创建一个新的注释 用于在环境变量设置时忽略输出 JSON 文件中的字段var false 我尝试使用JsonAnnotationIntrospector 但无法获得预期的输出 public class Vehicle String v
  • 按字母顺序对对象的 ArrayList 进行排序

    我必须创建一个方法来排序数组列表根据电子邮件按字母顺序排列对象 然后打印排序后的数组 我在排序时遇到麻烦的部分 我已经研究过并尝试使用Collections sort vehiclearray 但这对我不起作用 我是因为我需要一个叫做比较器
  • 在Java的System.out中以表格格式输出

    我正在从数据库获取结果 并希望将数据作为 Java 标准输出中的表输出 我尝试过使用 t 但我想要的第一列的长度变化很大 有没有办法将其显示在类似输出的漂亮表格中 Use System out format http java sun co

随机推荐

  • 多目标优化_学习笔记(二)NSGA-II

    前言 本篇博客出于学习交流目的 xff0c 主要是用来记录自己学习多目标优化中遇到的问题和心路历程 xff0c 方便之后回顾 过程中可能引用其他大牛的博客 xff0c 文末会给出相应链接 xff0c 侵删 xff01 REMARK xff1
  • 多目标优化_学习笔记(三)MOEA/D

    前言 本篇博客出于学习交流目的 xff0c 主要是用来记录自己学习多目标优化中遇到的问题和心路历程 xff0c 方便之后回顾 过程中可能引用其他大牛的博客 xff0c 文末会给出相应链接 xff0c 侵删 xff01 REMARK xff1
  • VNCViewer实现与WIN端文本复制粘贴

    主机系统 xff1a Win10 View端系统 xff1a Ubuntu 16 04 VNCViewer xff1a 6 17 今天踩的第二个坑 xff0c 主要还是因为懒 xff0c 有时候懒得打那么多字 xff0c 就想着和虚拟机一用
  • FGSM(Fast Gradient Sign Method)_学习笔记+代码实现

    前言 本篇博客出于学习交流目的 xff0c 主要是用来记录自己学习中遇到的问题和心路历程 xff0c 方便之后回顾 过程中可能引用其他大牛的博客 xff0c 文末会给出相应链接 xff0c 侵删 xff01 FGSM xff08 Fast
  • DeepFool对抗算法_学习笔记

    前言 本篇博客出于学习交流目的 xff0c 主要是用来记录自己学习中遇到的问题和心路历程 xff0c 方便之后回顾 过程中可能引用其他大牛的博客 xff0c 文末会给出相应链接 xff0c 侵删 xff01 DeepFool算法 特点 xf
  • 对抗样本黑箱攻击UPSET、ANGRI_学习笔记

    前言 本篇博客出于学习交流目的 xff0c 主要是用来记录自己学习中遇到的问题和心路历程 xff0c 方便之后回顾 过程中可能引用其他大牛的博客 xff0c 文末会给出相应链接 xff0c 侵删 xff01 DeepFool算法 特点 xf
  • One pixel 对抗攻击_学习笔记

    前言 本篇博客出于学习交流目的 xff0c 主要是用来记录自己学习中遇到的问题和心路历程 xff0c 方便之后回顾 过程中可能引用其他大牛的博客 xff0c 文末会给出相应链接 xff0c 侵删 xff01 One pixel 对抗攻击算法
  • 对抗样本可转移性与黑盒攻击_学习笔记

    前言 本篇博客出于学习交流目的 xff0c 主要是用来记录自己学习中遇到的问题和心路历程 xff0c 方便之后回顾 过程中可能引用其他大牛的博客 xff0c 文末会给出相应链接 xff0c 侵删 xff01 对抗样本可转移性与黑盒攻击深入研
  • VNC安装记录

    又是一次痛苦的安装过程 xff0c 记录一下避免再次踩坑 sudo apt get install tightvncserver 我安装的是tightvncserver 这个版本 xff0c 网上也有很多是vnc4server xff0c
  • ubuntu升级python版本

    Ubuntu16 04默认安装了Python2 7和3 5 请注意 xff0c 系统自带的python千万不能卸载 xff01 输入命令python 按Ctrl 43 D退出python命令行 输入命令sudo add apt reposi
  • Python microseconds 显示问题,及毫秒显示方法

    系统环境Ubuntu14 04 Python3 5 问题由来 xff1a 优化程序函数运行时间 xff0c 由于输入数据量比较大 xff0c 所以恰好且与1秒左右 xff0c 之前数据量小的数据集测试时用微秒 xff08 microseco
  • 关于ssh: connect to host XXX port 22: Connection timed out的解决办法

    今天想试着建立一个ss xff0c 结果犯了很多人在这里都会出现的错误 xff0c SSH连接不上 下面展现了笔者解决这个问题的流程 一 xff1a 查看master和data1 3的IP地址 当直接对data1 data2 data3进行
  • Matlab 应用GPU加速

    由于GPU近几年地迅速发展 xff0c GPU在多线程计算等方面逐渐超越CPU成为计算的主力军 而Matlab是常用的数学应用软件 xff0c 现在讲解一下如何在Matlab中使用GPU加速计算 文章目录 0 必要条件1 给GPU传输数据1
  • crt + xManager 远程打开linux 图形界面

    因为想要使用eclipse所以看了一下如何远程显示图形界面 1 安装eclipse c 43 43 xff1a sudo apt get install eclipse sudo apt get install eclipse cdt 2
  • keras.layers.upsampling2d

    span class token keyword from span keras span class token punctuation span layers span class token keyword import span U
  • (二)MapReduce整体流程

    1 MapReduce工作流程 1 MapReduce核心思想 图6 xff1a 采用 分而治之 思想 xff0c 将大数据集拆分到多个小数据块 xff0c 再转到多台机器上并行处理 总的来说Map任务独立执行被分割的数据 xff0c Re
  • 在 Linux 系统下使用badblocks检测硬盘上的坏道和坏块

    让我们从坏道和坏块的定义开始说起 xff0c 它们是一块磁盘或闪存上不再能够被读写的部分 xff0c 一般是由于磁盘表面特定的物理损坏或闪存晶体管失效导致的 随着坏道的继续积累 xff0c 它们会对你的磁盘或闪存容量产生令人不快或破坏性的影
  • 【已解决】NVIDIA-SMI has failed because it couldn‘t communicate with the NVIDIA driver 的报错

    问题描述 基于ubuntu16 04 xff0c 本人在更换一次系统下载源后 xff0c 误操作进行了内核升级 执行以下查看cuda命令 xff1a nvidia smi 出现如下提示 xff1a NVIDIA SMI has failed
  • python在图片上画矩形

    python在图片上画矩形 image path 61 39 39 image 61 cv2 imread image path first point 61 100 100 last point 61 100 100 cv2 rectan
  • Java中的线程池(3)----SingleThreadExecutor

    本文简单介绍Java中的另一种线程池 SingleThreadExecutor 创建SingleThreadExecutor的静态方法 首先还是先看一下创建SingleThreadExecutor的Executors下的静态方法 xff1a