当前位置: 首页 > news >正文

用 Collections.synchronizedSet 创建线程安全的 HashSet

       在 Java 中,HashSet 本身并不是线程安全的。如果在多线程环境下使用 HashSet,你需要采取额外的同步措施来保证线程安全。Collections 工具类提供了一种简便的方法来创建线程安全的集合——synchronizedSet 方法。这种方法通过在所有公共方法上添加同步块来确保线程安全。下面是如何使用 Collections.synchronizedSet 来创建一个线程安全的 HashSet,以及相关的注意事项和示例。

使用 Collections.synchronizedSet 创建线程安全的 HashSet

   Collections.synchronizedSet 方法接受一个 Set 实例作为参数,并返回一个线程安全的 Set。这个返回的 Set 对其所有公共方法进行了同步,因此可以在多线程环境中安全地使用。

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;public class SynchronizedHashSetExample {public static void main(String[] args) {// 创建一个线程安全的 HashSetSet<String> threadSafeSet = Collections.synchronizedSet(new HashSet<>());// 创建多个线程来测试线程安全性Runnable addTask = () -> {for (int i = ½; i < 100; i++) {threadSafeSet.add("Item " + i);}};Runnable removeTask = () -> {for (int i = ½; i < 100; i++) {threadSafeSet.remove("Item " + i);}};Thread t1 = new Thread(addTask);Thread t2 = new Thread(removeTask);t1.start();t2.start();try {t1.join();t2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Final set size: " + threadSafeSet.size());}
}

注意事项

  1. 迭代器的线程安全性

    • 通过 synchronizedSet 返回的 Set 的迭代器并不是线程安全的。如果你在多线程环境中迭代集合,需要手动进行同步。例如:
      synchronized (threadSafeSet) {for (String item : threadSafeSet) {// 处理 item}
      }
  2. 复合操作的原子性

    • 如果你执行的操作涉及多个步骤(例如,先检查某个元素是否存在,然后再添加或删除),你需要确保整个操作是原子性的。这通常意味着你需要在一个同步块内执行整个复合操作。
      synchronized (threadSafeSet) {if (!threadSafeSet.contains(element)) {threadSafeSet.add(element);}
      }
  3. 性能考量

    • 由于每个方法调用都需要获取锁,这可能会影响性能,特别是在高并发场景下。如果性能是一个关键因素,你可以考虑使用 ConcurrentHashMap.newKeySet() 方法来创建一个线程安全的 Set,它提供了更好的并发性能。

使用 ConcurrentHashMap.newKeySet()

   ConcurrentHashMap 类提供了一个 newKeySet() 方法,它可以创建一个线程安全的 Set。这个 Set 实现了 Set 接口,并且是基于 ConcurrentHashMap 的键集来实现的,因此它支持高效的并发访问。

import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;public class ConcurrentHashMapNewKeySetExample {public static void main(String[] args) {// 创建一个线程安全的 SetSet<String> threadSafeSet = ConcurrentHashMap.newKeySet();// 创建多个线程来测试线程安全性Runnable addTask = () -> {for (int i = ½; i < 100; i++) {threadSafeSet.add("Item " + i);}};Runnable removeTask = () -> {for (int i = ½; i < 100; i++) {threadSafeSet.remove("Item " + i);}};Thread t1 = new Thread(addTask);Thread t2 = new Thread(removeTask);t1.start();t2.start();try {t1.join();t2.join();} catch (InterruptedException e) {e.printStackTrace();}System.out.println("Final set size: " + threadSafeSet.size());}
}

总结

  • 使用 Collections.synchronizedSet 是一种简便的方法来创建线程安全的 HashSet,但需要注意迭代器和复合操作的同步。
  • 如果需要更高的并发性能,可以考虑使用 ConcurrentHashMap.newKeySet() 来创建一个线程安全的 Set

       这两种方法都可以有效地解决 HashSet 在多线程环境下的线程安全问题。选择哪种方法取决于你的具体需求和性能考量。

相关文章:

用 Collections.synchronizedSet 创建线程安全的 HashSet

在 Java 中&#xff0c;HashSet 本身并不是线程安全的。如果在多线程环境下使用 HashSet&#xff0c;你需要采取额外的同步措施来保证线程安全。Collections 工具类提供了一种简便的方法来创建线程安全的集合——synchronizedSet 方法。这种方法通过在所有公共方法上添加同步块…...

【深度学习】模型参数冻结:原理、应用与实践

在深度学习领域&#xff0c;模型参数冻结是一种重要的技术手段&#xff0c;它在模型训练和优化过程中有着广泛的应用。本文将详细介绍模型参数冻结的相关概念、应用场景、在代码中的实现方式以及一些实际的案例分析。 一、模型参数冻结的概念 在深度学习模型的训练过程中&…...

数字后端教程之Innovus report_property和get_property使用方法及应用案例

数字IC后端实现Innovus中使用report_property可以报告出各种各样object的属性&#xff0c;主要有cell&#xff0c;net&#xff0c;PG Net&#xff0c;Pin&#xff0c;时钟clock&#xff0c;时序库lib属性&#xff0c;Design属性&#xff0c;timing path&#xff0c;timin arc等…...

JS中console对象内部提供调试方法

console.log() console.log() 是最常用的输出方法&#xff0c;用于将信息输出到浏览器控制台&#xff0c;通常用于普通的调试信息。 用途: 打印普通的消息、变量、对象等。 let user { name: "Alice", age: 25 }; console.log(user); // 输出对象 console.log(&…...

python设计模式

一、单例模式 学习目标&#xff1a;掌握单例模式的作用和写法 可以明显的看出他两是独立的对象&#xff0c;而且是两个完全不同的id 当我们希望是s1和s2是同一个对象&#xff0c;这就是我们所说的单例模式。 最后获得的都是同一个对象&#xff0c;这样就可以避免去重复的创建…...

机器学习 笔记

特征值提取 字典 from sklearn.extaction import DictVectorizer mDictVectorizer(sparseFalse)#sparse是否转换成三元组形式 data[], #传入字典数据 data1model.fit_transform(data) #使用API 英文特征值提取 from sklearn.feature_extraction.text import CountVe…...

江协科技之STM32驱动1.3寸/0.96寸/0.91寸OLED显示屏介绍

目录 编码介绍 ASCII码 汉字编码 取模软件 江协科技OLED库适用器件 SSD1306简介 模块引脚更改 0.91寸OLED适配 模块驱动必备知识 驱动代码 OLED_Font.h OLED.h OLED.c 编码介绍 ASCII码 ASCII码是一套数字到字符的映射标准&#xff0c;它规定了用什么数字表示…...

Spring Security 认证流程,长话简说

一、代码先行 1、设计模式 SpringSecurity 采用的是 责任链 的设计模式&#xff0c;是一堆过滤器链的组合&#xff0c;它有一条很长的过滤器链。 不过我们不需要去仔细了解每一个过滤器的含义和用法,只需要搞定以下几个问题即可&#xff1a;怎么登录、怎么校验账户、认证失败…...

74HC245

74HC245&#xff1a;典型的CMOS型缓冲门电路 在这里用于增加电压...

Java的static关键字和静态代码块

一、当static关键字用来修饰属性时&#xff0c;所修饰的属性就是类属性&#xff0c;而不是对象属性&#xff0c;所以可以做到全类共享。 不能用对象名去调用&#xff0c;只能用类名调用。 二、静态方法只能调用同为静态的方法和属性&#xff0c;非静态方法什么都可以调用。 三…...

Apex 批处理将 account owner 转移,同时实现关联的 opp 和 case 转移

实现和 mass transfer account 一样的功能&#xff1a; global class AccountBatchScript implements Database.Batchable<sObject>,Schedulable{String query;Id oldOwnerId xxxxxxxxxxxx;Id newOwnerId yyyyyyyyyyyy;List<Id> AccountIds new List<Id>(…...

Python | Leetcode Python题解之第557题反转字符串中的单词III

题目&#xff1a; 题解&#xff1a; class Solution:def reverseWords(self, s: str) -> str:stack, res, s [], "", s " "for i in s:stack.append(i)if i " ":while(stack):res stack.pop()return res[1:]...

Spring设计模式

设计模式 是一种软件开发中的解决方案&#xff0c;设计原则。目的是使代码具有扩展性&#xff0c;可维护性&#xff0c;可读性&#xff0c;如&#xff1a; 单例模式&#xff08;Singleton Pattern&#xff09; Spring IoC 容器默认会将 Bean 创建为单例&#xff0c;保证一个类…...

信号保存和信号处理

目录 信号保存中重要的概念 内核中信号的保存 对sigset_t操作的函数 对block&#xff0c;pendding&#xff0c;handler三张表的操作 sigpromask ​编辑 sigpending 是否有sighandler函数呢&#xff1f; 案例 信号处理 操作系统是如何运行的&#xff1f; 硬件中断 …...

网站小程序app怎么查有没有备案?

网站小程序app怎么查有没有备案&#xff1f;只需要官方一个网址就可以&#xff0c;工信部备案查询官网地址有且只有一个&#xff0c;百度搜索 "ICP备案查询" 找到官方gov.cn网站即可查询&#xff01; 注&#xff1a;网站小程序app备案查询&#xff0c;可通过输入单位…...

如何利用宏和VBA来提高文档编辑排版速度?

一个真实的文档修改需求 为什么我会去研究VBA呢&#xff1f;主要原因是今年在一个项目里写了太多的文档。文档中很多操作其实都是机械的、重复的&#xff0c;但是偏偏又很耗时。举个例子&#xff0c;当时有这么一个修改需求&#xff0c;修改文档中所有“输入输出需求表格中”添…...

Kafka - 启用安全通信和认证机制_SSL + SASL

文章目录 官方资料概述制作kakfa证书1.1 openssl 生成CA1.2 生成server端秘钥对以及证书仓库1.3 CA 签名证书1.4 服务端秘钥库导入签名证书以及CA根证书1.5 生成服务端信任库并导入CA根数据1.6 生成客户端信任库并导入CA根证书 2 配置zookeeper SASL认证2.1 编写zk_server_jass…...

c++基础32输入和输出

输入和输出 C风格&#xff08;使用printf和scanf&#xff09;输出字符输入字符 C风格&#xff08;使用cin和cout&#xff09;输出字符输入字符 注意事项 在C和C中&#xff0c;字符的输入和输出可以通过多种方式实现&#xff0c;包括使用标准输入输出库函数如 printf和 scanf&…...

[C++] 函数详解

前言 今天zty带来的是函数的详解&#xff0c;搞了4个小时&#xff0c;大家给个赞呗&#xff0c;zty还要上学&#xff0c;发作品会少一点 先 赞 后 看 养 成 习 惯 先 赞 后 看 养 成 习 惯 先 赞 后 看 养 成 习 惯 演示用编译器及其…...

AMD CPU下pytorch 多GPU运行卡死和死锁解决

参考链接 https://medium.com/amitparekh/solving-ddp-deadlock-with-multiple-gpus-and-amd-cpus-442186632034 简要说明 AMD的IOMMU和NVIDIA的NCCL不兼容问题导致AMD的IOMMU是BIOS 级组件,它基本上充当将虚拟地址映射到 GPU 上的物理地址的接口,它的全部目的是让 CPU 和 G…...

调用支付宝接口响应40004 SYSTEM_ERROR问题排查

在对接支付宝API的时候&#xff0c;遇到了一些问题&#xff0c;记录一下排查过程。 Body:{"datadigital_fincloud_generalsaas_face_certify_initialize_response":{"msg":"Business Failed","code":"40004","sub_msg…...

智慧医疗能源事业线深度画像分析(上)

引言 医疗行业作为现代社会的关键基础设施,其能源消耗与环境影响正日益受到关注。随着全球"双碳"目标的推进和可持续发展理念的深入,智慧医疗能源事业线应运而生,致力于通过创新技术与管理方案,重构医疗领域的能源使用模式。这一事业线融合了能源管理、可持续发…...

java_网络服务相关_gateway_nacos_feign区别联系

1. spring-cloud-starter-gateway 作用&#xff1a;作为微服务架构的网关&#xff0c;统一入口&#xff0c;处理所有外部请求。 核心能力&#xff1a; 路由转发&#xff08;基于路径、服务名等&#xff09;过滤器&#xff08;鉴权、限流、日志、Header 处理&#xff09;支持负…...

进程地址空间(比特课总结)

一、进程地址空间 1. 环境变量 1 &#xff09;⽤户级环境变量与系统级环境变量 全局属性&#xff1a;环境变量具有全局属性&#xff0c;会被⼦进程继承。例如当bash启动⼦进程时&#xff0c;环 境变量会⾃动传递给⼦进程。 本地变量限制&#xff1a;本地变量只在当前进程(ba…...

【力扣数据库知识手册笔记】索引

索引 索引的优缺点 优点1. 通过创建唯一性索引&#xff0c;可以保证数据库表中每一行数据的唯一性。2. 可以加快数据的检索速度&#xff08;创建索引的主要原因&#xff09;。3. 可以加速表和表之间的连接&#xff0c;实现数据的参考完整性。4. 可以在查询过程中&#xff0c;…...

抖音增长新引擎:品融电商,一站式全案代运营领跑者

抖音增长新引擎&#xff1a;品融电商&#xff0c;一站式全案代运营领跑者 在抖音这个日活超7亿的流量汪洋中&#xff0c;品牌如何破浪前行&#xff1f;自建团队成本高、效果难控&#xff1b;碎片化运营又难成合力——这正是许多企业面临的增长困局。品融电商以「抖音全案代运营…...

oracle与MySQL数据库之间数据同步的技术要点

Oracle与MySQL数据库之间的数据同步是一个涉及多个技术要点的复杂任务。由于Oracle和MySQL的架构差异&#xff0c;它们的数据同步要求既要保持数据的准确性和一致性&#xff0c;又要处理好性能问题。以下是一些主要的技术要点&#xff1a; 数据结构差异 数据类型差异&#xff…...

Pinocchio 库详解及其在足式机器人上的应用

Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库&#xff0c;专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性&#xff0c;并提供了一个通用的框架&…...

在QWebEngineView上实现鼠标、触摸等事件捕获的解决方案

这个问题我看其他博主也写了&#xff0c;要么要会员、要么写的乱七八糟。这里我整理一下&#xff0c;把问题说清楚并且给出代码&#xff0c;拿去用就行&#xff0c;照着葫芦画瓢。 问题 在继承QWebEngineView后&#xff0c;重写mousePressEvent或event函数无法捕获鼠标按下事…...

MySQL 部分重点知识篇

一、数据库对象 1. 主键 定义 &#xff1a;主键是用于唯一标识表中每一行记录的字段或字段组合。它具有唯一性和非空性特点。 作用 &#xff1a;确保数据的完整性&#xff0c;便于数据的查询和管理。 示例 &#xff1a;在学生信息表中&#xff0c;学号可以作为主键&#xff…...