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

用 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) {
        // 创建一个线程安全的 HashSet
        Set<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) {
        // 创建一个线程安全的 Set
        Set<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.kler.cn/a/385924.html

相关文章:

  • 数据仓库在大数据处理中的作用
  • Spring中的Bean
  • CentOS7.9 源码编译 FreeSWITCH 1.10.12
  • Python学习------第八天
  • Spring Cloud Eureka 服务注册与发现
  • 一文学会docker中搭建kali
  • 健尔康在A股上市:市值84亿元,陈国平、陈麒宇父女成大赢家
  • 机器学习之集成学习算法
  • Mac M1下运行端到端语音模型Mini-Omni
  • 虚拟化数据恢复—XenServer虚拟机中SQL Server数据库数据恢复案例
  • STM32 BootLoader 刷新项目 (九) 跳转指定地址-命令0x55
  • GEE 案例——利用哨兵-2 图像时间序列和谷歌地球引擎云计算自动绘制和监测香港海洋水质参数
  • 蓝桥杯 Python组-神奇闹钟(datetime库)
  • 深入了解 curl:使用和功能详解
  • Android OpenGL ES详解——纹理过滤GL_NEAREST和GL_LINEAR的区别
  • 数据分析-41-时间序列预测之机器学习方法XGBoost
  • Spark Plan 之 SQLMetric
  • 电影插曲《牧羊曲》
  • 推荐一款面向增材制造的高效设计平台:nTopology
  • 新闻稿件管理:SpringBoot框架实战指南
  • css中pointer-events:none属性对div里面元素的鼠标事件的影响
  • qt QSyntaxHighlighter详解
  • 如何解决传统能源企业后备人才不足、人才规划缺失问题
  • IDEA启动JavaEE启动控制台乱码或者jsp等页面乱码
  • 【pytorch】Mujoco + 常用强化学习算法(持续更新)
  • npm安装记录