线程唯一的单例
经典设计模式的单例模式是指进程唯一的对象实例,实现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 …...
Android Wi-Fi 连接失败日志分析
1. Android wifi 关键日志总结 (1) Wi-Fi 断开 (CTRL-EVENT-DISCONNECTED reason3) 日志相关部分: 06-05 10:48:40.987 943 943 I wpa_supplicant: wlan0: CTRL-EVENT-DISCONNECTED bssid44:9b:c1:57:a8:90 reason3 locally_generated1解析: CTR…...
【Python】 -- 趣味代码 - 小恐龙游戏
文章目录 文章目录 00 小恐龙游戏程序设计框架代码结构和功能游戏流程总结01 小恐龙游戏程序设计02 百度网盘地址00 小恐龙游戏程序设计框架 这段代码是一个基于 Pygame 的简易跑酷游戏的完整实现,玩家控制一个角色(龙)躲避障碍物(仙人掌和乌鸦)。以下是代码的详细介绍:…...
【kafka】Golang实现分布式Masscan任务调度系统
要求: 输出两个程序,一个命令行程序(命令行参数用flag)和一个服务端程序。 命令行程序支持通过命令行参数配置下发IP或IP段、端口、扫描带宽,然后将消息推送到kafka里面。 服务端程序: 从kafka消费者接收…...
调用支付宝接口响应40004 SYSTEM_ERROR问题排查
在对接支付宝API的时候,遇到了一些问题,记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...
Leetcode 3576. Transform Array to All Equal Elements
Leetcode 3576. Transform Array to All Equal Elements 1. 解题思路2. 代码实现 题目链接:3576. Transform Array to All Equal Elements 1. 解题思路 这一题思路上就是分别考察一下是否能将其转化为全1或者全-1数组即可。 至于每一种情况是否可以达到…...
AI Agent与Agentic AI:原理、应用、挑战与未来展望
文章目录 一、引言二、AI Agent与Agentic AI的兴起2.1 技术契机与生态成熟2.2 Agent的定义与特征2.3 Agent的发展历程 三、AI Agent的核心技术栈解密3.1 感知模块代码示例:使用Python和OpenCV进行图像识别 3.2 认知与决策模块代码示例:使用OpenAI GPT-3进…...
Python爬虫实战:研究feedparser库相关技术
1. 引言 1.1 研究背景与意义 在当今信息爆炸的时代,互联网上存在着海量的信息资源。RSS(Really Simple Syndication)作为一种标准化的信息聚合技术,被广泛用于网站内容的发布和订阅。通过 RSS,用户可以方便地获取网站更新的内容,而无需频繁访问各个网站。 然而,互联网…...
质量体系的重要
质量体系是为确保产品、服务或过程质量满足规定要求,由相互关联的要素构成的有机整体。其核心内容可归纳为以下五个方面: 🏛️ 一、组织架构与职责 质量体系明确组织内各部门、岗位的职责与权限,形成层级清晰的管理网络…...
GC1808高性能24位立体声音频ADC芯片解析
1. 芯片概述 GC1808是一款24位立体声音频模数转换器(ADC),支持8kHz~96kHz采样率,集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器,适用于高保真音频采集场景。 2. 核心特性 高精度:24位分辨率,…...
JVM 内存结构 详解
内存结构 运行时数据区: Java虚拟机在运行Java程序过程中管理的内存区域。 程序计数器: 线程私有,程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个计数器完成。 每个线程都有一个程序计数…...
