用 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 在多线程环境下的线程安全问题。选择哪种方法取决于你的具体需求和性能考量。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/60270.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【网络安全渗透测试零基础入门】之SNMP放大攻击原理及实战演示,零基础入门到精通,收藏这一篇就够了!

前言 这是小强给粉丝盆友们整理的网络安全渗透测试入门阶段dos与ddos渗透与防御教程。 喜欢的朋友们&#xff0c;记得给我点赞支持和收藏一下&#xff0c;关注我&#xff0c;学习黑客技术。 SNMP&#xff08;Simple Network Management Protocol &#xff09;&#xff1a;简单…

el-dialog 设置 水平垂直居中 高度不固定

小记一下&#xff1a; 希望实现不管内容高度多少 el-dialog都能水平垂直居中 效果&#xff1a; css: .form-view-dialog{display: flex;align-items: center;justify-content: center;.el-dialog{margin: 0 auto; }.el-dialog__body{max-height: 75vh; // 可选择 设置一个最…

后端接口返回二进制文件,前端 window.opent预览展示

详细步骤 1.修改 PreviewApi 函数&#xff1a; 设置 responseType 为 ‘arraybuffer’&#xff0c;以接收二进制数据。 export const PreviewApi (data) > request({method: post,url: /dev-api/preview,responseType: arraybuffer,data });3.处理响应&#xff1a; 使用…

EMC Plus:外壳中的 PCB 演示

EMC Plus 提供了计算任何导入的近场源文件的字段统计信息的高级功能。在本演示中&#xff0c;我将指导您完成分析辐射电场的分步工作流程&#xff0c;特别是由 EMC Plus 中从 SIwave 导入的近场源产生的辐射电场。让我们开始吧&#xff01; 概述 以下模型是计算机机箱&#x…

【免越狱】iOS砸壳 可下载AppStore任意版本 旧版本IPA下载

软件介绍 下载iOS旧版应用&#xff0c;简化繁琐的抓包流程。 一键生成去更新IPA&#xff08;手机安装后&#xff0c;去除App Store的更新检测&#xff09;。 软件界面 支持系统 Windows 10/Windows 8/Windows 7&#xff08;由于使用了Fiddler库&#xff0c;因此需要.Net环境…

SQLite Where 子句

SQLite Where 子句 SQLite 是一种轻量级的数据库管理系统&#xff0c;广泛应用于移动设备和嵌入式系统。它支持标准的 SQL 语法&#xff0c;包括 SELECT, INSERT, UPDATE, DELETE 等命令。在执行这些命令时&#xff0c;WHERE 子句用于指定过滤条件&#xff0c;从而精确地控制操…

SpringBoot沙箱环境支付宝支付

1、创建应用 登录支付宝开放平台 支付宝开放平台网址 &#xff1a;支付宝 (alipay.com) 支付宝开放平台 下拉最下边 2、获取appId、支付宝公钥、应用私钥 3、开始创建spring boot项目 #支付宝支付配置 alipay:#你的APPIDappId: 902************#你的应用私钥privateKey: MIIE…

Ceph 中Crush 算法的理解

Crush&#xff08;Controlled Replication Under Scalable Hashing&#xff09;算法是一种可扩展的、分布式的副本数据放置算法&#xff0c;广泛用于存储系统中&#xff0c;特别是Ceph分布式存储系统中。以下是对CRUSH算法的详细解释&#xff1a; 一、算法原理 CRUSH算法根据…

计算机图形学 实验二 三维模型读取与控制

目录 一、实验内容 二、具体内容 (在实验2.3的基础上进行修改) 1、OFF格式三维模型文件的读取 2、三维模型的旋转动画 3、键盘鼠标的交互 4、模型的修改 三、代码 一、实验内容 读取实验提供的off格式三维模型&#xff0c;并对其赋色。利用鼠标和键盘的交互&#xff0…

FastGPT部署通义千问Qwen和智谱glm模型|OneAPI配置免费的第三方API

继这篇博客之后 从零开始FastGPT本地部署|Windows 有同学问&#xff0c;不想在多个平台申请API-Key&#xff0c;不好管理且要付费&#xff0c;有木有白嫖方案呀&#xff1f; 答&#xff1a;有啊。用硅基流动。 注册方法看这篇 【1024送福利】硅基流动送2000万token啦&#xff0…

SSE (Server-Sent Events) 服务器实时推送详解

Server-Sent Events 一、什么是 SSE ?二、SSE 的工作原理三、SSE 的基本配置1.HTTP 请求和响应头设置2.SSE 字段介绍3.SSE 事件数据流示例 四、SseEmitter 的基本配置1.SseEmitter 介绍及用法2.使用 SseEmitter 示例11)编写核心 SSE Client2)编写 Controller3)前端接收与处理 …

UE4/5 编译报错 MSB3073

UE4/5 编译报错 MSB3073 目录 UE4/5 编译报错 MSB3073 一、引言 二、方法1 三、方法2 四、方法3 一、引言 我们下载源代码之后编译时&#xff0c;可能会出现以下报错&#xff1a; MSB3073 命令“..\..\Build\BatchFiles\Rebuild.bat -Target"UE4Editor Win64 Devel…

Playwright 自动化测试与爬虫快速入门指南

1. 环境配置 # 安装 Playwright pip install playwright# 安装浏览器驱动 playwright install2. 基础用法 2.1 基本结构 from playwright.sync_api import sync_playwrightdef main():with sync_playwright() as p:# 启动浏览器&#xff0c;headlessFalse 可以看到浏览器界面…

等保测评中的常见问题总结

在信息安全等级保护测评&#xff08;等保测评&#xff09;过程中&#xff0c;企业常遇到的主要问题及其改进建议如下&#xff1a; ### 1. **安全责任不清** - **问题**&#xff1a;对于等保测评中涉及的安全责任&#xff0c;尤其是在使用云服务或外包服务时&#xff0c;企业…

Python学习从0到1 day28 Python 高阶技巧 ⑤ 多线程

若事与愿违&#xff0c;请相信&#xff0c;上天自有安排&#xff0c;允许一切如其所是 —— 24.11.12 一、进程、线程 现代操作系统比如Mac OS X&#xff0c;UNIX&#xff0c;Linux&#xff0c;Windows等&#xff0c;都是支持“多任务”的操作系统。 进程 进程&#xff1a;就…

LeetCode【0018】四数之和

本文目录 1 中文题目2 求解方法&#xff1a;双指针两层循环2.1 方法思路2.2 Python代码2.3 复杂度分析 3 题目总结 1 中文题目 给一个由 n n n 个整数组成的数组 n u m s nums nums &#xff0c;和一个目标值 t a r g e t target target 。请找出并返回满足下述全部条件且不…

扫雷游戏代码分享(c基础)

hi , I am 36. 代码来之不易&#x1f44d;&#x1f44d;&#x1f44d; 创建两个.c 一个.h 1&#xff1a;test.c #include"game.h"void game() {//创建数组char mine[ROWS][COLS] { 0 };char show[ROWS][COLS] { 0 };char temp[ROWS][COLS] { 0 };//初始化数…

智慧社区可视化解决方案:科技引领社区服务与管理新篇章

随着社会的发展&#xff0c;智慧社区作为新型城镇化发展目标和社区服务体系建设的重要举措&#xff0c;正逐步改变着我们的生活方式。智慧社区通过综合运用现代科学技术&#xff0c;整合区域资源&#xff0c;提升社区治理和服务水平&#xff0c;为居民提供更为便捷、高效、安全…

Nginx 的 proxy_pass 使用简介

proxy_pass 是 Nginx 中一个非常重要的指令&#xff0c;用于将请求代理到后端服务器。本文将详细介绍 proxy_pass 的基本用法、配置示例以及一些高级用法。 1. 基本概念 1.1 proxy_pass 概述 proxy_pass 指令用于将请求转发到后端服务器。它可以用于 HTTP 和 Stream 模块&am…

在 WPF 中,如何实现数据的双向绑定?

在 WPF 中&#xff0c;数据绑定是一个非常重要的特性&#xff0c;它允许 UI 与数据源之间自动同步。双向绑定是一种常见的绑定方式&#xff0c;当数据源更新时&#xff0c;UI 会自动更新&#xff1b;同样&#xff0c;当 UI 中的元素&#xff08;如文本框&#xff09;发生改变时…