Java并发编程(4)-同步容器和并发容器

同步类容器和并发类容器 一.为什么会出现同步容器? 在Java的集合容器框架中,主要有四大类别:List、Set、Queue、Map。 注意Collection和Map是顶层接口,而List、Set、Queue接口则分别继承了Collection接口,分别代表数组、集合和队列这三大类容器。 像ArrayList、LinkedList都是实现了List接口,HashSet实现了Set接口,而Deque(双向队列,允许... 阅读详情


更多关于Java并发编程的文章请点击这里:Java并发编程实践(0)-目录页


Java平台的类库包含了一个并发构造块的丰富集合,本篇将介绍在并发编程中十分常用的两种容器类,一是同步容器,二是并发容器,它们在某些特定的场合中可以用来替代我们常用的集合类,比如在高并发和多线程请求的情况下。
本篇总结自《Java并发编程实践》第五章 构造块 章节的内容,详情可以阅读该书。

一、同步容器

1.1、同步容器类介绍

同步容器类包括两部分,一个是Vector和Hashtable,它们是早期JDK的一部分;另一个是它们的同系容器,在JDK1.2之后才被 引入的同步包装类这些类是由Collections.synchronizedXxx工厂方法创建的。这些类通过封装它们的状态,并对每个公共方法进行了同步而实现了线程安全,这样一次只有一个线程能访问容器的状态。

1.2、常用的同步容器类

常用的同步容器类有Collections.synchronizedMap、Collections.synchronizedList、Collections.synchronizedSet、Collections.synchronizedSortSet、Collections.synchronizedSortMap,它们分别是Map、List、Set、SortSet、SortMap的同步容器类。

1.3、使用同步容器类的方式

使用同步容器类的方式很简单,如下代码就是使用了一个Map的同步类,对HashMap进行了包装。

//创建一个同步Map容器类,包装HashMap,使其线程安全
Map<String, String> synchronizedMap = Collections.synchronizedMap(new HashMap<String, String>());

接下来的操作和平时使用HashMap没有什么区别,常用的方法都没有改变:

		//存储key-value
         synchronizedMap.put("hello","world");
         
        //通过key读取value
        String hello = synchronizedMap.get("hello");
        System.out.println(hello);
        
        //判断key存在不存在,不存在则put
        synchronizedMap.putIfAbsent("arong","java");
1.4、同步容器类的实现机制

同步容器类的实现机制前面已经说过,其实就是依靠synchronized块对方法进行了同步,以阻止多个线程对一个方法进行并发的访问,从而使其达到线程安全的效果,以下是Collections.synchronizedMap的相关代码,我们可以看出,每个方法都被上锁了:

//static静态化使用户通过Collections类可直接获取到它
public static <K,V> Map<K,V> synchronizedMap(Map<K,V> m) {

		//这一步返回一个SynchronizedMap类,并将Map作为参数传入
        return new SynchronizedMap<>(m);
    }

	//真正的同步容器类
    private static class SynchronizedMap<K,V>
        ...
		//所有的方法中都使用了synchronized对有状态变量进行了同步
        public int size() {
            synchronized (mutex) {return m.size();}
        }
        public boolean isEmpty() {
            synchronized (mutex) {return m.isEmpty();}
        }
        public boolean containsKey(Object key) {
            synchronized (mutex) {return m.containsKey(key);}
        }
        public boolean containsValue(Object value) {
            synchronized (mutex) {return m.containsValue(value);}
        }
        public V get(Object key) {
            synchronized (mutex) {return m.get(key);}
        }

        public V put(K key, V value) {
            synchronized (mutex) {return m.put(key, value);}
        }
        public V remove(Object key) {
            synchronized (mutex) {return m.remove(key);}
        }
        public void putAll(Map<? extends K, ? extends V> map) {
            synchronized (mutex) {m.putAll(map);}
        }
        public void clear() {
            synchronized (mutex) {m.clear();}
        }

      ...
1.5、使用同步容器类的弊端

同步容器类虽然能保证在多线程请求的情况下容器数据的安全,但是弊端也是比较明显的:所有的方法都是同步的,每次只能有一个线程获得锁,其他线程全部阻塞,这样会导致性能问题,所以说,在对性能的要求不高,但是要求安全性良好的情况下,可以使用同步容器类,但是如果希望容器在并发请求时能同时接受多个线程的处理,并且也能保证线程安全的话,推荐使用下文介绍的并发容器类。

二、并发容器

2.1、什么是并发容器类

Java5.0通过提供几个并发的容器类来改进同步容器。同步容器通过对容器的所有状态进行串行访问。从而实现了它们的线程安全。这样做的代价是削减了并发性,当多个线程共同竞争容器级的锁时,吞吐量就会降低。另一方面,并发容器是为了多线程并发访问而设计的。Java5.0添加了ConcurentHashMap来替代同步的HashMap实现;当多数操作为读取操作时,CopyOnWriteArrayList是List相应的同步实现。新的ConcurrentMap接口还加入了常见复合操作,比如“缺少即加入(put-if-absent)”、替换和条件删除等。并发容器类位于java.util.concurrent,即并发包下。

2.2、CAS算法

CAS是一种无锁的非阻塞算法,全称为:Compare-and-swap(比较并交换),大致思路是:先比较目标对象现值是否和旧值一致,如果一致,则更新对象为新值;如果不一致,则表明对象已经被其他线程修改,直接返回。

2.3、ConcurrentHashMap

ConcurrentHashMap实现了HashTable的所有功能,线程安全,但却在检索元素时不需要锁定,因此效率更高。ConcurrentHashMap的key 和 value都不允许null出现。原因在于ConcurrentHashMap不能区分出value是null还是没有map上,相对的HashMap却可以允许null值,在于其使用在单线程环境下,可以使用containKey(key)方法提前判定是否能map上,从而区分这两种情况,但是ConcurrentHashMap在多线程使用上下文中则不能这么判定。在并发编程中,常用来替换Collections.synchronizeHashMap。

2.4、CopyOnWriteArrayList

CopyOnWriteArrayList提供高效地读取操作,使用在读多写少的场景。CopyOnWriteArrayList读取操作不用加锁,且是安全的;写操作时,先copy一份原有数据数组,再对复制数据进行写入操作,最后将复制数据替换原有数据,从而保证写操作不影响读操作。在并发编程中,常常用来替换Collections.synchronizedList。

Java高并发编程实战8,同步容器与并发容器 Java基础教程系列,打造精品专栏。 阅读详情

相关推荐

Java并发编程:从同步容器到并发容器的演进

本文将深入探讨Java中的同步容器和并发容器,包括它们的概念、工作原理、使用方法以及性能分析。我们将从同步容器的基础开始,逐步介绍并发容器的出现和演进,最后讨论如何在实际开发中选择合适的容器,并提供一些最佳实践和未来发展的展望。通过本文,读者将能够更好地理解Java并发编程中容器的重要性和如何有效地利用它们来提高程序的并发性能和线程安全性。

fudaihb的博客 1601

【并发编程】同步容器与并发容器

【并发编程】同步容器与并发容器

互联网小阿祥 899

【Java并发编程】6.常见并发容器

跳表 简而言之跳表就是多层链表的结合体,跳表分为许多层(level),每一层都可以看作是数据的索引,这些索引的意义就是加快跳表查找数据速度。每一层的数据都是有序的,上一层数据是下一层数据的子集,并且第一层(level 1)包含了全部的数据;层次越高,跳跃性越大,包含的数据越少。并且随便插入一个数据该数据是否会是跳表索引完全随机的跟玩骰子一样,redis中的zset底层就是跳表数据结构。并且跳表的速...

sowhat 3149

Java同步容器和并发容器

每一个 segment 都是一个 HashEntry[] table, table 中的每一个元素本质上都是一个 HashEntry 的单向队列。比如 table[3]为首节点,table[3]->next 为节点 1,之后为节点 2,依次类推。在对 Vector 等容器并发地进行迭代修改时,会报 ConcurrentModificationException 异常,关于这个异常将会在后续文章中讲述。修饰的方法,每次只允许一个线程执行,其他试图访问这个方法的线程只能等待。同步容器未必真的安全。

2301_78145669的博客 539

树莓派小车:智能捡球小车——Q宝

在遇到第一个直角右转口后,进入阶段二,阶段二是智能小车减速,因为速度过快可能导致车头下方的检测出现小毛病,小车进入第一个左拐路口,增加左转时间,然后直行,到横线处,小车停止,进入阶段三,小车先识别前方的球类,然后倒车到拐口处,原地右转,之后的识别也是类似的操作,随后有一个简单的避障功能,进行球类识别测试时,在本地测试效果良好,但是投入实际应用中时,受到光线等因素的影响,识别球类的能力大大下降。小车摄像头精度不够,视角较小,在识别人脸时,需要不断移动人脸照片,让摄像头能够抓取人脸。在第一阶段的循迹过程中,

dfbsszxzv的博客 1933

告别重打包:在Android 9上实现免Root的Frida-Gadget持久化Hook(附AOSP源码修改详解)

本文详细介绍了在Android 9上实现免Root的Frida-Gadget持久化Hook技术方案。通过修改AOSP源码,绕过传统重打包方式面临的签名校验和完整性检查,实现在非Root环境下的系统级Hook。文章包含核心代码修改、编译配置调整及调试技巧,为移动安全研究提供高效稳定的解决方案。

weixin_33726313的博客 501

Java同步容器类

例如,某些线程在可以访问容器之前,必须等待迭代过程结束,如果容器的规模很大,或者在每个元素上执行操作的时间很长,那么这些线程将长时间等待。这种方式的好坏取决于多个因素,包括容器的大小,在每个元素上执行的工作,迭代操作相对于容器其他操作的调用频率,以及在响应时间和吞吐量等方面的需求。容器上常见的复合操作包括:迭代(反复访问元素,直到遍历完容器中所有元素)、跳转(根据指定顺序找到当前元素的下一个元素)以及条件运算,例如“若没有则添加”(检查在Map 中是否存在键值K,如果没有,就加入二元组(K,V))。

2301_78102191的博客 489

【Attention Is All You Need】Transformer模型精读

Attention Is All You Need》这篇论文奠定了Transformer模型的基础,为深度学习的发展提供了新的方向。Transformer通过自注意力机制和并行化处理显著提升了计算效率和模型性能。然而,Transformer的广泛应用也带来了新的挑战,如计算资源的消耗和对长序列的处理能力等。随着技术的不断发展,研究人员已经提出了诸如Efficient Transformer、Reformer等变种,旨在提升Transformer的效率和适应性。

Lewiz_124的博客 1499

并发(六、并发容器)

同步容器、并发容器、CopyOnWriteArrayList、ConcurrentHashMap、ArrayBlockingQueue、LinkedBlockingQueue、ConcurrentLinkedQueue 简介及基本使用

天行健,君子以自强不息 947

密码学:一文读懂数字证书

消息摘要算法用于验证数据完整性服务,对称加密算法和非对称加密算法用于保证数据保密性服务,数字签名算法用于抗否认性服务。数字证书集合了多种密码学算法:自身带有公钥信息,可完成相应的加密/解密操作;同时,还带有数字签名,可鉴别消息来源;且自身带有消息摘要信息,可验证证书的完整性;由于证书本身含有用户身份信息,因而具有认证性。

Shujie 2913

高效复用PCB设计:Cadence Sub-Drawing跨项目复制技巧

本文详细介绍了Cadence Allegro中Sub-Drawing功能的应用技巧,帮助PCB工程师高效复用成熟设计模块。通过分步教学,从精准导出到完美导入,并提供了解决坐标错位与DRC冲突的实用避坑指南。掌握这一技巧能显著提升设计效率,实现团队知识的标准化积累与快速复用。

weixin_29172201的博客 404

Java容器有哪些?哪些是同步容器,哪些是并发容器?

Java容器有哪些?哪些是同步容器,哪些是并发容器?一、基本概念新的改变功能快捷键合理的创建标题,有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants创建一个自定义列表如何创建一个注脚注释也是必不可少的KaTeX数学公式新的甘特图功能,丰富你的文章UML 图表FLowchart流程图导出与导入导出导入...

u013030086的博客 6964

深入解析CycloneDDS跨域通信中的XML配置文件优化策略

本文深入解析了CycloneDDS跨域通信中XML配置文件的优化策略,重点介绍了网络接口配置、多播设置、性能调优参数及复杂场景下的配置案例。通过实战技巧和调试方法,帮助开发者在SoC环境中实现高效稳定的跨域通信,提升系统性能。

soda5的博客 689

【Java并发编程】同步容器与并发容器

探讨Java的同步容器和并发容器

明月沉江春雾晓 2756

AI在保险产品定价优化中的创新应用

在当今保险市场中,准确合理的产品定价是保险公司实现可持续发展的关键因素之一。传统的保险产品定价主要基于经验数据和精算模型,但这种方式往往存在数据处理效率低、对复杂风险因素考虑不足等问题。本文的目的在于深入探讨AI技术如何在保险产品定价中进行创新应用,以提高定价的准确性、效率和灵活性,更好地满足市场需求和客户个性化需求。本文的范围涵盖了AI技术在保险产品定价各个环节的应用,包括风险评估、费率计算、产品设计等方面。同时,还会涉及到相关的核心算法、数学模型以及实际应用案例等内容。

欢迎来到我的优快云空间!这里聚焦AI大模型应用实战,分享前沿技术、实战案例与开发经验。 983

STM32CubeMX | 38-使用硬件SPI驱动以太网模块(W5500)

本篇详细的记录了如何使用STM32CubeMX配置STM32L431RCT6的硬件SPI外设与以W5500通信,驱动以太网模块。 1. 准备工作 硬件准备 开发板 首先需要准备一个开发板,这里我准备的是STM32L4的开发板(BearPi): W5500以太网模块 这里我使用常见的以太网模块W5500: W5500官网 http://www.w5500.cn/ W5500中文手册 iEthernet W5500 Datasheet 软件准备 需要安装好Keil - MDK及芯片对应的包,以

Mculover666的博客(嵌入式) 7389

同步容器与并发容器类简介

同步容器类   同步容器类包括Vector和HashTable,二者都是早期JDK的一部分,此外还包括在JDK1.2当中添加的一些功能相似的类,这些同步的封装类是由Collections.synchronizedXxx等工厂方法创建的。这些类实现线程安全的方式是:将它们的状态封装起来,并对每个公有方法都进行同步,使得每次都只有一个线程能够访问容器的状态。相较于并行容器,同步容器的实现原理其实很简...

寻光人cyh的博客 5959

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Java 容器--同步容器和并发容器

Java 中的容器主要可以分为四个大类,分别是ListMapSet和Queue,但并不是所有的 Java 容器都是线程安全的。说到线程安全的问题,我们先来理解两个名词同步容器和并发容器。

qq_24907431的博客 1287

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

大中型超市收银系统(可直接运行)

光步前台收银系统系统功能:商品销售、商品退货、挂单、收银员权限、会员销售、单品取消、整单取消、商品查询、脱机销售、脱机数据上传,基本资料下载,开钱箱、小票打印、收款结算,支持多币种付款方式(现金、储值卡、礼券、微信等),支持多种促销。运行环境:.net 4.0登陆信息用户名:1001 密码:123456内置商品信息,商品编码可输入00001000 - 00010000,测试效果相关功能键F5 结算 F9挂单 F11商品查询 F8退货 Insert单品取消 Del整单取消 F12开钱箱F2 会员 Ctrl+Z退出系统 Home 锁屏 相关源码待公开

Java并发:整理自《Java并发编程实战》和《Java并发编程的艺术》

声明:Java并发的内容是自己阅读《Java并发编程实战》和《Java并发编程的艺术》整理来的。 图文并茂请戳 思维导图下载请戳 目录 (1)基础概念 (2)线程 (3)锁 (4)同步器 (5)并发容器和框架 (6)Java并发工具类 (7)原子操作类 (8)Executor框架(执行机制) (9)其他 (一).基础概念 1.可见性和原子性 可见性:一个线程...

liuffei的专栏 1884

efm32 入门.pdf

本PDF共计22页,介绍的是操作驱动API,下载与否自己斟酌。

java并发编程之同步容器

1、同步容器 包括两部分:一个是vector,一个是hashtable,其他容器类如果需要同步,可以调用Collections.synchronizedXXX接口,成为同步容器类,接口如下所示: 2、同步容器的问题        同步的容器是线程安全的,但是如果对同步容器进行复合操作,则会出现问题,复合操作主要包括:迭代(反复获取元素,直到获取容器的最后一个元素)、导航、以及条件元素,比

Just Do It! 2104

Java并发编程:同步容器、并发容器和阻塞队列

为了方便编写出线程安全的程序,Java里面提供了一些线程安全类和并发工具,比如:同步容器、并发容器、阻塞队列、Synchronizer(比如CountDownLatch)。一.为什么会出现同步容器在Java的集合容器框架中,主要有四大类别:List、Set、Queue、Map。如果有多个线程并发地访问这些容器时,就会出现问题。因此,在编写程序时,必须要求程序员手动地在任何访问到这些容器的地方进行同步

Mook的博客 1385

【Java 并发编程】详解

在并发编程中,使用普通的集合类(如 ArrayList、HashMap 等)往往会出现线程安全问题,因为它们在设计时并没有考虑多线程并发访问的情况。Java 提供了一系列并发容器来解决这个问题,这些并发容器在保证高效性能的同时,能够支持多线程安全地进行读写等操作。

架构师之路 1123

关于Java并发编程的总结和思考

编写优质的并发代码是一件难度极高的事情。Java语言从第一版本开始内置了对多线程的支持,这一点在当年是非常了不起的,但是当我们对并发编程有了更深刻的认识和更多的实践后,实现并发编程就有了更多的方案和更好的选择。本文是对并发编程的一点总结和思考,同时也分享了Java 5以后的版本中如何编写并发代码的一点点经验。

骆昊的技术专栏 16万+
上一篇: Java并发编程(3)-如何构造线程安全应用
下一篇: Java并发编程(5)-Executor线程调度框架的使用
BoringRong
BoringRong 领域专家: 后端开发技术领域 领域专家: 后端开发技术领域
博客等级 码龄9年 2万+粉丝 386原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

BoringRong

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值