使用静态内部类单例模式创建自定义线程池

article/2025/9/17 19:47:35

一、使用场景

1、有时候业务上A端和B端做接口传输消息,B端收到消息后做进一步数据处理(持久化或者解析)等耗时的操作,如果是同步操作会造成等待、超时等情况。可以先向A端返回一个收到信息的消息,再多线程异步处理数据,处理完成之后根据业务需求向A端返回处理完成的信息。

二.静态内部类创建单例的好处

1.这个类的实例化是靠静态内部类的常量实例化的,只会加载一次赋值一次,随着静态内部类一起加载。

2.懒汉式、饿汉式有线程安全问题,需要加同步锁才能实现线程安全。才用静态内部类的话是线程安全的,理由同上。

三.自定义线程池的好处

我们都知道Java有4种线程池分别是:

1.newSingleThreadExecutor 单一的线程池

2.newFixedThreadPool 固定大小的线程池

3.newCachedThreadPool 自动扩大的线程池

4.newScheduledThreadPool 支持定时和周期性任务的线程池

但是都不建议使用,因为他们源码层面都是去调用ThreadPoolExecutor类,填充七个参数来执行的,所以更建议直接new一个ThreadPoolExecutor类,通过填充七大参数来实现自定义控制,更加明确线程池的运行规则,规避资源耗尽的风险。

 自定义线程ThreadPoolExecutor七大参数详解

1.corePoolSize:核心线程数

2.maximumPoolSize:线程池能够容纳的最大线程数

3.keepAliveTime:超时等待时间

4.timeUnit:时间单位

5.workqueue:等待进入线程池的任务缓存队列

6.threadFactory:线程执行工厂

7.handler:拒绝策略

其中拒绝策略又分为四种:

1.AbortPolicy:丢弃任务,并抛出异常,阻塞系统正常工作。

2.DiscardPolicy:丢弃无法处理的任务,不处理,不抛异常;允许任务丢失的话,是一种好策略。

3.DiscardOldestPolicy:丢弃队列最前面的任务,重新提交被拒绝的任务(喜新厌旧)

4.CallerRunsPolicy:只要线程池没关闭,直接在调用者线程中运行当前没丢弃的任务。对性能可能有影响

四、使用静态内部类单例模式创建线程池,并测试使用线程池里的线程异步处理消息

1.静态内部类创建线程池

public class SyncDataThreadPool {private static class SingletonHolder {/*使用自定义线程池,7个参数依次代表1、核心线程数2、最大线程数3、超时等待时间4、时间单位5、允许等待的线程数6、执行工厂7、拒绝策略(这里使用拒绝后续线程并抛异常的策略)*/private static ExecutorService threadPool = new ThreadPoolExecutor(5,10,30,TimeUnit.SECONDS,new LinkedBlockingDeque<>(5),Executors.defaultThreadFactory(),new ThreadPoolExecutor.AbortPolicy());}public SyncDataThreadPool() {}public static ExecutorService newInstance() {return SingletonHolder.threadPool;}

2.编写业务代码,使用sleep模拟同步数据或者解析文件等比较耗时的操作

@ApiOperation(value = "测试", notes = "测试")
@PostMapping(value = "/test")
public String test(HttpServletRequest request , HttpServletResponse response) throws IOException {ExecutorService threadPool = SyncDataThreadPool.newInstance();log.info("当前线程池:"+threadPool.toString()+"它的hashcode为:"+threadPool.hashCode());//通过toString和hashCode方法查看是否是同一个实例,保证单例threadPool.execute(new Runnable() {@Overridepublic void run() {log.info("模拟解析文件开始,调用线程池的线程:"+Thread.currentThread().getName());//获取当前线程的名字try {Thread.sleep(10000);//模拟耗时的处理任务} catch (InterruptedException e) {e.printStackTrace();}log.info("模拟解析文件结束,调用线程池的线程:"+Thread.currentThread().getName());//获取当前线程的名字/*** 这里可以写回调A端的接口反馈消息* */}});
    log.info("-------------------返回认证方法了------------------------");return "ok";
}

 3.10秒内快速执行2次Controller方法之后的打印信息

可以看到,是同一个线程池(保证单例)里面两个不同的线程(多线程)异步执行了模拟持久化的操作,并且后面打印“返回认证方法了”在执行线程之前返回,实现了使用静态内部类单例模式创建线程池并异步执行的效果。


http://chatgpt.dhexx.cn/article/FIdgRfBF.shtml

相关文章

Kotlin 静态内部类单例模式的正确实现方式

本篇是对现网上流传的 Kotlin 实现静态内部类单例模式的纠正&#xff0c;为了把原理说清楚&#xff0c;文章前奏可能会有些长&#xff0c;熟悉静态内部类单例模式原理的朋友&#xff0c;可以直接跳转到文章最后&#xff0c;直接看结果即可。 最近在整理基础库的时候&#xff0c…

设计模式3:单例模式:静态内部类单例模式

单例模式最简单的写法就是静态内部类单例模式&#xff0c;如下&#xff1a; public class Manager {private static class ManagerHolder {private static Manager instance new Manager();}private Manager() {}public static Manager getInstance() {return ManagerHolder.i…

单例模式详解

微信搜索【程序员囧辉】&#xff0c;关注这个坚持分享技术干货的程序员。 概述 单例模式&#xff0c;是一种常用的软件设计模式。在它的核心结构中只包含一个被称为单例的特殊类。通过单例模式可以保证系统中&#xff0c;使用单例模式的类只有一个对象实例。 单例应用场景 Wi…

MATLAB中的结构体数组(struct)学习笔记

不要失却热情&#xff0c;不要丢掉冠军的心&#xff01; MALAB中的结构体&#xff08;struct&#xff09;数组学习笔记 前言1. 版本2. 关键词 一、Struct结构体数组概述二、Struct结构体数组基本用法1. 结构体的创建2. 结构体中的筛选操作 前言 MATLAB中结构体数组基本用法笔…

MATLAB学习——结构体类型

前言 MATLAB 中的数据类型主要包括数值类型、 逻辑类型、 字符串、函数句柄、 结构体和单元数组类型。 这6种基本的数据类型都是按照数组形式存储和操作的。 一、结构体类型 MATLAB中的结构体与C语言中的结构体类似&#xff0c; 一个结构体可以通过字段存储多个不同类型的数…

Matlab将结构体struct字段内的数据转化到矩阵中

假设structure1,为一结构体&#xff0c;structure1.name为100个字符串 怎么将这些字符串不用循环一次性赋值到矩阵A?? Astructure1.name 为什么只是将第一个赋值过去&#xff1f; 答案是可以使用cat函数&#xff1a; 可以用cat函数&#xff0c; A cat(1,structur1.name)是…

Matlab:结构体数组

Matlab:结构体数组 创建标量结构体访问字段中的值对非标量结构体数组进行索引当您有要按名称组织的数据时,可以使用结构体来存储这些数据。结构体将数据存储在名为字段的容器中,然后您可以按指定的名称访问这些字段。使用圆点表示法创建、分配和访问结构体字段中的数据。如果…

Matlab-结构数组

1 认识结构数组 结构也是一种数据类型&#xff0c;它的每一个元素都有一个名字。称结构中的元素为域。 类似与C语言中的结构体。 2 创建 两种方法&#xff1a; &#xff08;1&#xff09;用赋值语句创建 &#xff08;2&#xff09;用函数 struct 函数进行创建 2.1 赋值语…

Matlab遇到结构体内容引用自非结构体数组对象

原因&#xff1a; 未初始化下一级结构体的值&#xff0c;如果直接调用就会报错。 举例&#xff1a; a.p[]; a.p.x解决方法&#xff1a; 需要先初始化&#xff0c;再调用 a.p.x[] or a.p.x0

Matlab:结构体Struct

Matlab中创建一个结构体数组的方式有两种&#xff0c;分别为直接引用方式和使用struct函数。 1、使用直接引用方式创建结构体 与建立数值型数组一样&#xff0c;建立新struct对象不需要事先申明&#xff0c;可以直接引用&#xff0c;而且可以动态扩充。比如建立一个复数变量x…

Matlab 结构体(struct)使用

转自http://blog.sina.com.cn/s/blog_468651400100c6c0.html 要在MALTAB中实现比较复杂的编程&#xff0c;就不能不用struct类型。而且在 MATLAB中实现struct比C中更为方便。 4. 3.1 结构数组的创建 MATLAB提供了两种定义结构的方式&#xff1a;直接应用和使用struct函数。 1. …

MATALB-结构体

结构体 结构体的生成一、 直接输入二、使用结构体生成函数struct 结构体的操作添加成员变量删除成员变量调用成员变量 结构体是另一种可以将不同类型数据组合在一起的数据类型。 MATLAB结构体变量类似于C语言结构体变量,且比C语音更加直观。 结构体与单元数组的区别为,结构体…

matlab学习-结构体变量

matlab结构体学习 matlab结构体学习 matlab结构体与C语言数据结构结构体或java语言类的定义有异曲同工之妙&#xff0c;其主要知识点如下 提示&#xff1a;写完文章后&#xff0c;目录可以自动生成&#xff0c;如何生成可参考右边的帮助文档 文章目录 matlab结构体学习前言一…

matlab-结构体struct

在前面&#xff0c;有用到一个cell2struct&#xff08;&#xff09;函数&#xff0c;cell是单元数组&#xff0c;而struct就是结构体。 1.建立结构体&#xff0c;在matlab中建立结构体有两种方式&#xff0c; eg&#xff1a;第一种为直接赋值 >> stu(1).namezhangsan;…

matlab中结构体使用方法

转自 http://hi.baidu.com/dess2211/blog/item/bb9b80185a7f940334fa417c.html matlab中使用结构体 2008-01-15 14:23 结构(struct)数组 要在MALTAB中实现比较复杂的编程&#xff0c;就不能不用struct类型。而且在 MATLAB中实现struct比C中更为方便。 4. 3.1 结构数组的创建 MA…

Matlab中结构体struct创建和使用

在项目上遇见了调用api接口&#xff0c;接口返回的信息为struct&#xff0c;故探讨一下matlab的struct结构体 1、struct结构体创建 创建结构体数组有两种方式&#xff0c;分别为直接创建和使用struct函数 1.1 直接创建 直接定义字段&#xff0c;像使用一般matlab变量一样&…

matlab 结构体

在前面&#xff0c;有用到一个cell2struct&#xff08;&#xff09;函数&#xff0c;cell是单元数组&#xff0c;而struct就是结构体。 1.建立结构体&#xff0c;在matlab中建立结构体有两种方式&#xff0c; eg&#xff1a;第一种为直接赋值 >> stu(1).namezhangsan; …

单片机实例4——广告灯的左移右移(硬件电路图+汇编程序+C语言程序)

4&#xff0e; 广告灯的左移右移 1&#xff0e; 实验任务 做单一灯的左移右移&#xff0c;硬件电路如图4.4.1所示&#xff0c;八个发光二极管L1&#xff0d;L8分别接在单片机的P1.0&#xff0d;P1.7接口上&#xff0c;输出“0”时&#xff0c;发光二极管亮&#xff0c;开始时P…

蓝桥杯-左移右移(2022国赛)

蓝桥杯-左移右移 1、问题描述2、解题思路与代码实现2.1 方法一&#xff1a;使用LinkedList双向链表实现(50%)2.2 方法二&#xff1a;使用HashMap左右临界值实现(100%) 1、问题描述 小蓝有一个长度为 N 的数组, 初始时从左到右依次是 1,2,3,…N 。 之后小蓝对这个数组进行了 M 次…

第十三届蓝桥杯大赛软件类决赛Java大学B组C题——左移右移

【问题描述】 小蓝有一个长度为 N 的数组&#xff0c;初始时从左到右依次是 1, 2, 3, . . . N。 之后小蓝对这个数组进行了 M 次操作&#xff0c;每次操作可能是以下 2 种之一&#xff1a; 左移 x&#xff0c;即把 x 移动到最左边。右移 x&#xff0c;即把 x 移动到最右边。 …