Java并发容器详解,及使用场景
并发容器的由来
在Java并发编程中,经常听到Java集合类,同步容器、并发容器,那么他们有哪些具体分类,以及各自之间的区别和优劣呢?
只有把这些梳理清楚了,你才能真正掌握在高并发的环境下,正确使用好并发容器,我们先从Java集合类,同步容器谈起。

1.什么是同步容器
Java的集合容器框架中,主要有四大类别:List、Set、Queue、Map,大家熟知的这些集合类ArrayList、LinkedList、HashMap这些容器都是非线程安全的。
如果有多个线程并发地访问这些容器时,就会出现问题。因此,在编写程序时,在多线程环境下必须要求程序员手动地在任何访问到这些容器的地方进行同步处理,这样导致在使用这些容器的时候非常地不方便。
所以,Java先提供了同步容器供用户使用。
同步容器可以简单地理解为通过synchronized来实现同步的容器,比如Vector、Hashtable以及SynchronizedList等容器。
2.同步容器,主要的分类:
- Vector
- Stack
- HashTable
- Collections.synchronized方法生成
同步容器面临的问题
可以通过查看Vector,Hashtable等这些同步容器的实现代码,可以看到这些容器实现线程安全的方式就是将它们的状态封装起来,并在需要同步的方法上加上关键字synchronized。
这样做的代价是削弱了并发性,当多个线程共同竞争容器级的锁时,吞吐量就会降低。
例如: HashTable只要有一条线程获取了容器的锁之后,其他所有的线程访问同步函数都会被阻塞,因此同一时刻只能有一条线程访问同步函数。
因此为了解决同步容器的性能问题,所以才有了并发容器。
什么是并发容器
java.util.concurrent包中提供了多种并发类容器。
并发类容器是专门针对多线程并发设计的,使用了锁分段技术,只对操作的位置进行同步操作,但是其他没有操作的位置其他线程仍然可以访问,提高了程序的吞吐量。
采用了CAS算法和部分代码使用synchronized锁保证线程安全。
并发容器有哪些分类

对应的非并发容器:HashMap
目标:代替Hashtable、synchronizedMap,支持复合操作
原理:JDK6中采用一种更加细粒度的加锁机制Segment“分段锁”,JDK8中采用CAS无锁算法。
对应的非并发容器:ArrayList
目标:代替Vector、synchronizedList
原理:利用高并发往往是读多写少的特性,对读操作不加锁,对写操作,先复制一份新的集合,在新的集合上面修改,然后将新集合赋值给旧的引用,并通过volatile 保证其可见性,当然写操作的锁是必不可少的了。
3.CopyOnWriteArraySet
对应的非并发容器:HashSet
目标:代替synchronizedSet
原理:基于CopyOnWriteArrayList实现,其唯一的不同是在add时调用的是CopyOnWriteArrayList的addIfAbsent方法,其遍历当前Object数组,如Object数组中已有了当前元素,则直接返回,如果没有则放入Object数组的尾部,并返回。
4.ConcurrentSkipListMap
对应的非并发容器:TreeMap
目标:代替synchronizedSortedMap(TreeMap)
原理:Skip list(跳表)是一种可以代替平衡树的数据结构,默认是按照Key值升序的。
5.ConcurrentSkipListSet
对应的非并发容器:TreeSet
目标:代替synchronizedSortedSet
原理:内部基于ConcurrentSkipListMap实现
不会阻塞的队列
对应的非并发容器:Queue
原理:基于链表实现的FIFO队列(LinkedList的并发版本)
7.LinkedBlockingQueue、ArrayBlockingQueue、PriorityBlockingQueue
对应的非并发容器:BlockingQueue
特点:拓展了Queue,增加了可阻塞的插入和获取等操作
原理:通过ReentrantLock实现线程安全,通过Condition实现阻塞和唤醒
实现类:
- LinkedBlockingQueue:基于链表实现的可阻塞的FIFO队列
- ArrayBlockingQueue:基于数组实现的可阻塞的FIFO队列
- PriorityBlockingQueue:按优先级排序的队列
Java并发容器详解,及使用场景的更多相关文章
- 最强Java并发编程详解:知识点梳理,BAT面试题等
本文原创更多内容可以参考: Java 全栈知识体系.如需转载请说明原处. 知识体系系统性梳理 Java 并发之基础 A. Java进阶 - Java 并发之基础:首先全局的了解并发的知识体系,同时了解 ...
- 【Java并发】详解 AbstractQueuedSynchronizer
前言 队列同步器 AbstractQueuedSynchronizer(以下简称 AQS),是用来构建锁或者其他同步组件的基础框架.它使用一个 int 成员变量来表示同步状态,通过 CAS 操作对同步 ...
- 【Java 并发】详解 ThreadLocal
前言 ThreadLocal 主要用来提供线程局部变量,也就是变量只对当前线程可见,本文主要记录一下对于 ThreadLocal 的理解.更多关于 Java 多线程的文章可以转到 这里. 线程局部变量 ...
- 【Java 并发】详解 ThreadPoolExecutor
前言 线程池是并发中一项常用的优化方法,通过对线程复用,减少线程的创建,降低资源消耗,提高程序响应速度.在 Java 中我们一般通过 Exectuors 提供的工厂方法来创建线程池,但是线程池的最终实 ...
- Java并发synchronized详解
今天和大家一起学习下并发编程,先举一个简单的生活例子,我们去医院或者银行排队叫号,那每个工作人员之间如何保证不会叫重号呢? public class TicketDemo extends Thread ...
- Java线程池详解(二)
一.前言 在总结了线程池的一些原理及实现细节之后,产出了一篇文章:Java线程池详解(一),后面的(一)是在本文出现之后加上的,而本文就成了(二).因为在写完第一篇关于java线程池的文章之后,越发觉 ...
- 云时代架构阅读笔记六——Java内存模型详解(二)
承接上文:云时代架构阅读笔记五——Java内存模型详解(一) 原子性.可见性.有序性 Java内存模型围绕着并发过程中如何处理原子性.可见性和有序性这三个特征来建立的,来逐个看一下: 1.原子性(At ...
- Java volatile关键字详解
Java volatile关键字详解 volatile是java中的一个关键字,用于修饰变量.被此关键修饰的变量可以禁止对此变量操作的指令进行重排,还有保持内存的可见性. 简言之它的作用就是: 禁止指 ...
- storm源码之理解Storm中Worker、Executor、Task关系 + 并发度详解
本文导读: 1 Worker.Executor.task详解 2 配置拓扑的并发度 3 拓扑示例 4 动态配置拓扑并发度 Worker.Executor.Task详解: Storm在集群上运行一个To ...
- 转:Java HashMap实现详解
Java HashMap实现详解 转:http://beyond99.blog.51cto.com/1469451/429789 1. HashMap概述: HashMap是基于哈希表的M ...
随机推荐
- 【问题解决】java.lang.SecurityException: JCE cannot authenticate the provider BC
问题复现 历史项目升级JDK(由1.7升级到8),进行加密/解密时出现报错java.lang.SecurityException: JCE cannot authenticate the provid ...
- 机器学习专业词汇:“Lookahead horizon” 可以翻译为“前瞻视距”或“预见范围”
"Lookahead horizon" 可以翻译为"前瞻视距"或"预见范围". 在不同领域中,它可能具有稍微不同的含义: 在机器学习和人工智 ...
- 服务器漏洞修复:TLS 1.0 已启用、HSTS、CSP
1.TLS 1.0 已启用 描述: 此 Web 服务器支持通过 TLS 1.0 加密.TLS 1.0 不被认为是"强密码术".根据 PCI 数据安全标准 3.2(.1) 的定义和要 ...
- pytest框架之fixture
1.在进行接口关联时,一般很多个接口共用一个上行接口(例如)登录,可以使用fixture定义一个测试夹具,将登录的接口写在框架的conftest.py文件中: @pytest.fixture(scop ...
- mysql8创建用户
create user test_user@'%' identified by 'test2022@'; grant all privileges on test.* to test_user@'%' ...
- 不错的PHP扩展
不错的PHP扩展 ext name ext description ds data structure 提供list hash queue等数据结构 igbinary 数据压缩(速度快 压缩后内容小) ...
- JS 正则表示式 字符串匹配 忽略大小写
在项目中遇到了需要使用字符串进行正则匹配,同时还要忽略大小写可以按照以下方法:1 先使用new RegExp(newVal, 'i')生成需要匹配的规则,其中 'i' 表示忽略大小写2 再对相应的字符 ...
- MySQL用错了,99%的人已中招
在我们日常工作中,可能会经常使用MySQL数据库,因为它是开源免费的,而且性能还不错. 在国内的很多公司中,经常被使用. 但我们在MySQL使用过程中,也非常容易踩坑,不信继续往下看. 今天这篇文章重 ...
- Educational Codeforces Round 102 (Rated for Div
Educational Codeforces Round 102 (Rated for Div. 2) No More Inversions 给定\(k\),序列\(a\)长度为\(n\):\(1,2 ...
- 升级Linux内核版本
```shell# 查看内核版本,jw版本ceph默认format=2, 2.x 及之前的的内核版本需手动调整format=1# 4.x之前要关闭object-map fast-diff deep-f ...