Java中线程安全的集合类

news2024/9/30 23:34:18

在先前的文章中我们已经讲过了原子类(线程安全的基本类型,基于CAS实现),详见常见锁策略,synchronized内部原理以及CAS-CSDN博客 ,我们在来讲一下集合类,在原来的集合类,大多数是线程不安全的,虽然vector,Stack,HashTable 是线程安全的,但由于其在一些关键方法上都加了synchronized,导致同时读以及单线程中也要加锁,于是java官方已经将其标为不安全类,不建议使用了,那我们如何在多线程下保证安全的使用一些集合类。

 多线程环境下使用ArrayList

1)自己使用同步机制(synchronized或者ReentrantLock)具体内容可以看这里Java线程安全问题以及解决方案-CSDN博客

2)使用Collections.synchronizedList()

List<String> synchronizedList = Collections.synchronizedList(new ArrayList<>());

用这种方式创建出的synchronizedList在关键方法上都具有synchronized

3)使用CopyOnWriteArrayList

CopyOnWriteArrayList 是 Java 中的一种并发集合类,它提供了一种在迭代时保证线程安全的机制。它的特点是在对集合进行修改(添加、删除元素)时,不直接在原始数据上进行操作,而是先将原始数据复制一份,然后在副本上进行修改,最后再将修改后的副本替换原始数据,且同时写时也会创建出两个拷贝。这种机制保证了在迭代过程中不会发生并发修改异常(ConcurrentModificationException),因为每次迭代都是在集合的一个固定的副本上进行的。

import java.util.concurrent.CopyOnWriteArrayList;

public class ConcurrentListExample {
    private static final int THREAD_COUNT = 3;
    private static final int OPERATIONS_PER_THREAD = 10000;

    private static CopyOnWriteArrayList<Integer> list = new CopyOnWriteArrayList<>();

    public static void main(String[] args) {
        // 创建并启动多个线程进行写操作
        for (int i = 0; i < THREAD_COUNT; i++) {
            Thread writerThread = new Thread(() -> {
                for (int j = 0; j < OPERATIONS_PER_THREAD; j++) {
                    list.add(j);
                }
            });
            writerThread.start();
        }

        // 创建并启动多个线程进行读操作
        for (int i = 0; i < THREAD_COUNT; i++) {
            Thread readerThread = new Thread(() -> {
                for (int j = 0; j < OPERATIONS_PER_THREAD; j++) {
                    int size = list.size(); // 读取列表大小
                    System.out.println("List size: " + size);
                    try {
                        Thread.sleep(10); // 模拟其他处理
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
            });
            readerThread.start();
        }
    }
}

列表大小的变化:读线程会定期读取列表的大小并打印出来。由于写线程在不断地往列表中添加元素,因此列表的大小会逐渐增加。读线程每次读取到的列表大小可能会不同,取决于它在列表大小被修改之前或之后读取到的。读线程的竞争:由于多个读线程同时进行,它们可能会竞争访问 CopyOnWriteArrayList 的大小。因此输出结果中可能会出现多个读线程同时读取列表大小并打印的情况。写线程的竞争:多个写线程同时向 CopyOnWriteArrayList 中添加元素,它们之间也可能存在竞争。因此,列表中的元素可能会以不确定的顺序被添加。

如何安全地使用 CopyOnWriteArrayList

  1. 并发读写安全CopyOnWriteArrayList 在迭代时提供了线程安全的保证,因此可以安全地在多个线程中进行读操作和写操作,而无需额外的同步控制。

  2. 适用场景:适用于读操作远远多于写操作的场景,因为每次写操作都会触发一次数组的拷贝,可能会带来一定的性能开销。

  3. 实时性:需要注意,由于写操作会对原始数据进行拷贝,因此在写操作完成之前,迭代器可能会遍历到老的数据。如果需要实时性较高的结果,可能需要其他方式进行处理。

  4. 性能考虑:虽然 CopyOnWriteArrayList 提供了线程安全的迭代机制,但在写操作频繁的情况下,可能会产生较高的开销,因为每次写操作都需要拷贝整个数组。因此,对于写操作频繁的场景,可能需要考虑其他更合适的并发集合类。

总的来说,CopyOnWriteArrayList 是一种适用于读多写少的场景下保证线程安全的并发集合类,能够有效地解决在多线程环境中的并发访问问题。

多线程环境使用哈希表

HashMap 本身不是线程安全的,我们可以使用Hashtable, ConcurrentHashMap

Hashtable

  1. 线程安全性

    • Hashtable 是线程安全的,所有的公共方法都是同步的,因此可以在多线程环境中安全地使用。
  2. 性能

    • Hashtable 的所有方法都是同步的,而且是对整个HashTable加锁,这意味着在高并发的情况下可能会出现性能瓶颈。因为每次操作都需要获得锁来保证线程安全性。
    • Hashtable 使用一个称为扩容阈值(Expansion Threshold)的参数来控制何时需要进行扩容。当添加元素时,如果元素数量超过了当前容量乘以加载因子(Load Factor),就会触发扩容操作。默认情况下,加载因子是 0.75。扩容操作会创建一个新的数组,大小是原数组的两倍加一,然后将原有数据重新哈希到新数组中。因为 Hashtable 的所有方法都是同步的,所以在进行扩容时会锁定整个哈希表,可能会引起性能不稳定。

ConcurrentHashMap

  1. 线程安全性
    • ConcurrentHashMap 通过使用分段锁(Segment Locking)来实现线程安全性,它将整个存储空间分成多个段(Segment),每个段拥有自己的锁,这里的段在Java8以后可以简单理解成HashAMap的每一个链表或者树,锁对象则是链表头节点或者树的根节点,因此可以在大部分情况下实现更高的并发度。在Java 8及以后的版本中,ConcurrentHashMap 使用了 CAS (Compare and Swap) 操作来进一步提高性能,比如在size()方法上使用CAS实现了轻量级锁,避免了重量级锁的出现。
  2. 性能
    • 由于 ConcurrentHashMap 使用了分段锁和 CAS 操作,因此在高并发的情况下,通常比 Hashtable 的性能要好。它提供了更好的并发性能,更适合大规模并发访问的场景。
    • 在添加元素时,ConcurrentHashMap 在初始化时会创建一定数量的段,每个段内部都是一个独立的哈希表。当添加元素时,只会锁定对应段的锁,其他段的数据仍然可以被并发访问。
    • 扩容操作会在添加元素时自动触发,并且是分段进行的。每个段在达到一定的容量阈值时会触发扩容操作,而不是等待整个哈希表的容量达到阈值。
    • ConcurrentHashMap 的扩容是分段进行的,因此不会阻塞整个哈希表,可以在一定程度上提高并发性能。

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

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

相关文章

深入了解 Android 中的 RelativeLayout 布局

RelativeLayout 是 Android 中常用的布局之一&#xff0c;它允许开发者基于子视图之间的相对位置来排列界面元素。在这篇博客中&#xff0c;我们将详细介绍 RelativeLayout 的各种属性&#xff0c;并提供代码示例和解释。 第一个示例 <RelativeLayoutandroid:layout_width…

【数据分享】2001~2023年中国区域MOD17A3HGF GPP数据

各位同学们好&#xff0c;今天和大伙儿分享的是2001~2023年中国区域MOD17A3HGF GPP数据。如果大家有下载处理数据等方面的问题&#xff0c;您可以私信或评论。 Running, S., M. Zhao. <i>MODIS/Terra Net Primary Production Gap-Filled Yearly L4 Global 500m SIN Grid…

标准库`random`函数大全:探索Python中的随机数生成【第107篇—`random`函数大全】

标准库random函数大全&#xff1a;探索Python中的随机数生成 随机数在计算机科学和数据科学领域中扮演着重要角色&#xff0c;Python的标准库中提供了random模块&#xff0c;用于生成各种随机数。本篇博客将深入探讨random模块的各种函数&#xff0c;以及它们的应用场景和代码…

Leetcoder Day35| 动态规划part02

62.不同路径 一个机器人位于一个 m x n 网格的左上角 &#xff08;起始点在下图中标记为 “Start” &#xff09;。 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角&#xff08;在下图中标记为 “Finish” &#xff09;。 问总共有多少条不同的路径&#xff…

如何在2.2.1版Aduino IDE中开发ESP32

ESP32芯片集成了WIFI和蓝牙&#xff0c;而且关于生态也很不错&#xff0c;越来越多的学习者和开发者选择此类芯片&#xff0c;而不像用keil开发STM32或者51一样&#xff0c;ESP32虽然也有官方的ESP32-IDF开发软甲&#xff0c;但是经过我个人的实操体验&#xff0c;不适合小白或…

基于Springboot的人事管理系统 (有报告)。Javaee项目,springboot项目。

演示视频&#xff1a; 基于Springboot的人事管理系统 &#xff08;有报告&#xff09;。Javaee项目&#xff0c;springboot项目。 项目介绍&#xff1a; 采用M&#xff08;model&#xff09;V&#xff08;view&#xff09;C&#xff08;controller&#xff09;三层体系结构&am…

ctf_show笔记篇(web入门---文件包含)

目录 文件包含 78-79&#xff1a;最基础的文件包含&#xff0c;使用伪协议&#xff0c;大小写绕过或者通配符绕过&#xff0c;再或者使用其他方法 ​编辑80-81&#xff1a;可采用日志文件绕过或者大小写绕过&#xff08;81只能日志文件绕过&#xff09; ####80-86&#xff1…

linux系统---nginx(3)核心配置指令及调优

目录 Nginx 核心配置指令 一、Nginx配置文件详解 1、配置文件目录 2、配置文件结构 二、调优 1、在全局域进行的调优 1.1线程池指令 1.2 工作进程数指令 2.1 工作进程并非数指令 2.2 事件处理机制选择指令 2.3 互斥锁指令 3、在http指令域的调优 3.1 Nginx端口监听…

无所不谈,百无禁忌,Win11本地部署无内容审查中文大语言模型CausalLM-14B

无内容审查机制大模型整合包,基于CausalLM-14B量化 目前流行的开源大语言模型大抵都会有内容审查机制&#xff0c;这并非是新鲜事&#xff0c;因为之前chat-gpt就曾经被“玩”坏过&#xff0c;如果没有内容审查&#xff0c;恶意用户可能通过精心设计的输入&#xff08;prompt&a…

leetcode刷题记录:动态规划02,子序列问题

参考labuladong的算法小抄整理 link 子序列问题&#xff0c;用一维dp数组或二维dp数组来解决。 一维数组&#xff1a;最大子数组和&#xff0c;最长递增子序列。dp[i]的定义&#xff1a;在子数组 arr[0…i] 中&#xff0c;以 arr[i] 结尾的子序列的长度是 dp[i]。二维数组&…

【Vue3】解锁Vue3黑科技:探索接口、泛型和自定义类型的前端奇迹

&#x1f497;&#x1f497;&#x1f497;欢迎来到我的博客&#xff0c;你将找到有关如何使用技术解决问题的文章&#xff0c;也会找到某个技术的学习路线。无论你是何种职业&#xff0c;我都希望我的博客对你有所帮助。最后不要忘记订阅我的博客以获取最新文章&#xff0c;也欢…

【大数据架构(3)】Lambda vs. Kappa Architecture-选择你需要的架构

文章目录 一. Data Processing Architectures1. Lambda Architecture1.1. 架构说明a. Data Ingestion Layerb. Batch Layer (Batch processing)c. Speed Layer (Real-Time Data Processing)d. Serving Layer 1.2. Lambda Architecture的优缺点1.3. 使用案例 2. Kappa Architect…

【风格迁移】StyTr2:引入 Transformer 解决 CNN 在长距离依赖性处理不足和细节丢失问题

StyTr2&#xff1a;引入 Transformer 解决 CNN 在长距离依赖性处理不足和细节丢失问题 提出背景StyTr2 组成StyTr2 架构 提出背景 论文&#xff1a;https://arxiv.org/pdf/2105.14576.pdf 代码&#xff1a;https://github.com/diyiiyiii/StyTR-2 问题&#xff1a; 传统的神经…

NOC2023软件创意编程(学而思赛道)python初中组初赛真题

软件创意编程 一、参赛范围 1.参赛组别:小学低年级组(1-3 年级)、小学高年级组(4-6 年级)、初中组。 2.参赛人数:1 人。 3.指导教师:1 人(可空缺)。 4.每人限参加 1 个赛项。 组别确定:以地方教育行政主管部门(教委、教育厅、教育局) 认定的选手所属学段为准。 二、…

云主机和传统主机到底有什么区别呢?

随着信息技术的快速发展&#xff0c;企业对IT基础设施的要求越来越高&#xff0c;许多问题等待解决&#xff1a;政府传统部署扩容升级麻烦、公司服务器维护周期长、建设和维护成本低等。运营成本高&#xff1b; 安全稳定性差、数据易丢失等问题亟待解决。 云主机的出现很大程度…

蓝桥杯集训·每日一题2024 (前缀和)

笔记&#xff1a; 例题&#xff1a; #include<bits/stdc.h> using namespace std; const int N 5000010; char str[N]; int s[N]; int main(){int t;cin>>t;for(int a1;a<t;a){int n;cin>>n;scanf("%s",str1);for(int i1;i<n;i){s[i]s[i-1]…

【教学类-36-12】20240302对称画右脸或左脸(中班《幼儿园里朋友多》)(midjounery-v 5.1 Python图片切割)

作品展示&#xff1a; 背景需求&#xff1a; 中班《幼儿园里朋友多》操作材料包——画对称脸 尝试用midjounery获得更多幼儿正脸图形&#xff0c;切割一半&#xff0c;制作相似的学具 一、MJ获取简笔画图案 风变编程——MJ 第1个关键词 Childrens face, front, simple stro…

switch开关语句

定义 单条件多分支的开关语句。 格式定义 switch(表达式) { case 常量值1: 若干个语句 break; ... case 常量值n: 若干个语句 break; default: 若干语句 } ★注意★&#xff1a; ① 表达式的值必须与int兼容类型&#xff1a; byte&#xff0c;short&#xff0c;int&#xff…

CI/CD笔记.Gitlab系列.`gitlab-ci.yml`中的头部关键字

CI/CD笔记.Gitlab系列 gitlab-ci.yml中的头部关键字 - 文章信息 - Author: 李俊才 (jcLee95) Visit me at: https://jclee95.blog.csdn.netMy WebSite&#xff1a;http://thispage.tech/Email: 291148484163.com. Shenzhen ChinaAddress of this article:https://blog.csdn.ne…

解读OWASP应用安全验证标准ASVS

OWASP应用程序安全验证标准&#xff08;OWASP Application Security Verification Standard&#xff0c;ASVS&#xff09;为测试web应用程序技术安全控制提供了基础&#xff0c;还为开发人员提供了安全开发的要求列表。 1. 简介 OWASP应用安全验证标准&#xff0c;是一份测试应…