Java多线程并发之同步容器和并发容器-第一篇
Java多线程并发之同步容器和并发容器-第一篇
概述
本文主要讲解在Java多线程并发开发中,集合中有哪些支持并发的的。什么是同步容器(集合),什么是并发容器(集合)?并发容器分类有哪些?每个分类都有哪些类?
本文是《凯哥分享Java并发编程之J.U.C包讲解》系列教程中的第五篇。如果想系统学习,凯哥(kaigejava)建议从第一篇开始看。
从本篇开始,我们就来讲解讲解Java的并发容器。大致思路:先介绍什么是并发容器。然后讲解list相关的、map相关的以及队列相关的。这个系列会有好几篇文章。大家最好跟着一篇一篇学。
正文开始
回顾Java中常用的容器(集合):
我们知道Java内部的容器类是集合相关的。主要包括:List接口、Map接口以及Set接口及其子类。
Collection及Map体系如下图:
我们常用的类关系简化版:
上图中少了一个类:Properties.这个类用的比较少。
我们来简单复习下Java中集合子类及数据结构:
|
顶级接口 |
二级接口 |
子类 |
数据结构 |
|
Collection |
List |
Arraylist |
顺序结构动态数组类【数组结构】 |
|
LinkedList |
链表结构 |
||
|
Vector |
向量 |
||
|
Stack |
栈(是Vector的子类) |
||
|
Set |
HashSet |
哈希表结构(底层是HashMap) |
|
|
Treeset |
二叉树结构(红黑树)(底层treeMap) |
||
|
LinkedHashSet |
|||
|
Map |
HashMap |
链表散列(一个数组和链表的结合体) |
|
|
TreeMap |
二叉树 |
||
|
Hashtable |
哈希表 |
说明:关于hashMap是如何解决hash冲撞问题,可以详见凯哥写的:《hashMap怎么保证hash一致性的》这篇文章详细介绍了。
我们知道,绝大部分常用的集合都是线程不安全的,但是也有线程安全的。
其中线程安全的类有:
List接口下的Vector【及Stack(因为stack是Vector的子类)】
Map接口下的:HashTable【及properties(因为properties是HashTable的子类)】
我们来看看为什么vector和HashTable是线程的安全的?
查看vector源码中add方法:
在来看看HashTable源码中put方法:
发现了吗?无论是vector还是hashTable都是使用了Synchronized关键之修饰的。使用了互斥同步锁机制来保证线程安全性的。
在JDK 1.5版本之前,如果想要保证线程安全,使用这两个类或者使用Collections工具类的Synxxx方法来保证线程的安全。
同步容器:
这些使用类Synchronized关键字修饰的容器被称为:同步容器
同步容器的缺点:
但是我们知道使用互斥锁Synchronized在并发下是很影响效率的。那是因为将并行强制转换成串行的。加互斥锁后,只有等一个锁用完之后,下一个才可以接着使用。很影响效率。
在现在大数据高并发下,有没有更好的解决方案呢?当然有的,在JDK1.5版本之后,JDK内部为我们提供了一些并发容器。
并发容器
在一般情况不考虑并发和线程安全性问题的时候,我们使用非线程安全的集合效率更高,如果需要考虑线程安全,不考虑并发或者并发很小的情况下,可以使用同步容器。但是如果在高并发下,同步容器就不能使用了。可以使用并发容器。Java中并发容器在Java.util.concurrent包下。
Concurrent包下有很多并发相关的,本篇我们就来扒拉扒拉众多并发相关类中和并发容器相关的十几个类:
并发容器分类
大致可以分以下三类:
1:List相关的并发容器
2:Map/Set相关的并发容器
为什么把Set划分到Map这个分类下呢?因为在Java的设计中,Set可以理解为阉割版的Map.说白了就是只有Key没有Value的Map.
3:队列相关的并发容器
从名字后缀我们就可以进行区分出来。三个分类相关类如下表:
|
分类名称 |
类名 |
说明 |
数据结构 |
|
List相关的并发容器类 |
CopyOnWriteArrayList |
并发版的ArrayList |
|
|
Map/Set相关的并发容器 |
ConcurrentHashMap |
并发版的HashMap |
|
|
CopyOnWriteArraySet |
并发版的Set |
||
|
ConcurrentSkipListMap |
基于跳表的并发Map |
||
|
ConcurrentSkipListSet |
基于跳表的并发Set |
||
|
队列相关的并发容器 |
ConcurrentLinkedQueue |
并发对垒 |
基于链表数据结构的 |
|
ConcurrentLinkedDeque |
并发队列 |
基于双向链表结构 |
|
|
ArrayBlockingQueue |
阻塞队列 |
基于数组结构 |
|
|
LinkedBlockingDeque |
阻塞对垒 |
基于双向链表结构 |
|
|
PriorityBlockingQueue |
线程安全的优先队列 |
||
|
SynchronousQueue |
读写成对的队列 |
||
|
LinkedTransferQueue |
基于链表的数据交换队列 |
||
|
DelayQueue |
延时队列 |
题外话:通过上表,我们可以看出JDK中类命名规则。
1:Map/Set相关的就以Map/Set结尾;List相关的就以list结尾
2:当选队列都已queue结尾;双向队列都已Deque结尾。
这种类名命名规范:见名知意。在我们自己写代码的时候类命名也应该这样。
言归正传,我们接着来讲解。先来看看第一个类。List对应的并发类.
再下一篇文章中,我们将详细讲解list对应的并发容器以及用代码来测试ArrayList、vector以及CopyOnWriteArrayList在100个线程向list中添加1000个数据后的比较。

Java多线程并发之同步容器和并发容器-第一篇的更多相关文章
- java多线程总结-同步容器与并发容器的对比与介绍
1 容器集简单介绍 java.util包下面的容器集主要有两种,一种是Collection接口下面的List和Set,一种是Map, 大致结构如下: Collection List LinkedLis ...
- Java并发——同步容器与并发容器
同步容器类 早期版本的JDK提供的同步容器类为Vector和Hashtable,JDK1.2 提供了Collections.synchronizedXxx等工程方法,将普通的容器继续包装.对每个共有方 ...
- Java并发—同步容器和并发容器
简述同步容器与并发容器 在Java并发编程中,经常听到同步容器.并发容器之说,那什么是同步容器与并发容器呢?同步容器可以简单地理解为通过synchronized来实现同步的容器,比如Vector.Ha ...
- Java并发(9)- 从同步容器到并发容器
引言 容器是Java基础类库中使用频率最高的一部分,Java集合包中提供了大量的容器类来帮组我们简化开发,我前面的文章中对Java集合包中的关键容器进行过一个系列的分析,但这些集合类都是非线程安全的, ...
- Java多线程-线程的同步(同步方法)
线程的同步是保证多线程安全访问竞争资源的一种手段.线程的同步是Java多线程编程的难点,往往开发者搞不清楚什么是竞争资源.什么时候需要考虑同步,怎么同步等等问题,当然,这些问题没有很明确的答案,但有些 ...
- Java——多线程之对象及变量的并发访问
Java多线系列文章是Java多线程的详解介绍,对多线程还不熟悉的同学可以先去看一下我的这篇博客Java基础系列3:多线程超详细总结,这篇博客从宏观层面介绍了多线程的整体概况,接下来的几篇文章是对多线 ...
- java多线程---4 线程同步介绍及不安全案例说明
java多线程---4 线程同步介绍及不安全案例说明 线程同步 并发: 同一个对象被多个线程同时操作. 处理多线程问题时,多个线程访问同一个对象,并且某些线程还想修改这个对象,这时候我们就需要线程同步 ...
- 关于Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇高质量的博文)
Java多线程的线程同步和线程通信的一些小问题(顺便分享几篇质量高的博文) 前言:在学习多线程时,遇到了一些问题,这里我将这些问题都分享出来,同时也分享了几篇其他博客主的博客,并且将我个人的理解也分享 ...
- Java中常用的七个阻塞队列介绍第一篇
Java中常用的七个阻塞队列介绍第一篇 在上一篇我们对Java中的队列分类做了简单的介绍.本文咱们主要来聊聊阻塞队列中的七个常用子类.这七个阻塞队列的学习步骤:先看源码,分析完源码之后,我们再来对每个 ...
- 【Java并发编程二】同步容器和并发容器
一.同步容器 在Java中,同步容器包括两个部分,一个是vector和HashTable,查看vector.HashTable的实现代码,可以看到这些容器实现线程安全的方式就是将它们的状态封装起来,并 ...
随机推荐
- HTML手稿
没有一张图解决不了的事:https://www.processon.com/mindmap/5ccebc48e4b0841b844a23fb 1.网页中web 标准的三层组成? W3C 万维网联盟 结 ...
- C++ 中的 lowbit
lowbit 的定义 首先了解 lowbit 的定义 \(lowbit(n)\) ,为 \(n\) 的二进制原码中最低的一位 \(1\) 以及其后面的 \(0\) 所表示的数 举个简单的例子: 将 \ ...
- oeasy教您玩转linux010210管理应用aptitude
上一部分我们都讲了什么? 下载并运行了 hollywood hollywood 更新了源的信息 sudo apt update 查看所有已经安装的软件包 # dpkg deiban 本地包管理 dpk ...
- 解读GaussDB(for MySQL)灵活多维的二级分区表策略
本文分享自华为云社区<GaussDB(for MySQL)创新特性:灵活多维的二级分区表策略>,作者:GaussDB 数据库. 背景介绍 分区表及二级分区表的功能,可以让数据库更加有效地管 ...
- C#/.NET这些实用的编程技巧你都会了吗?
DotNet Exercises介绍 DotNetGuide专栏C#/.NET/.NET Core编程常用语法.算法.技巧.中间件.类库练习集,配套详细的文章教程讲解,助你快速掌握C#/.NET/.N ...
- JavaScript小技巧~将伪数组转成数组的方法
伪数组:具有数组结构但是五数组相关方法的类数组结构: 方式1:Array.from() 方式2:Array.prototype.slice.call(); 用方式1吧,好记简单
- 题解:CF1957A Stickogon
CF1957A Stickogon 题意 题意十分简单,给予你 \(n\) 个棍子,问这些棍子可以构成多少个正多边形. 思路 说是可以构成多少个正多边形,所以我们可以用边最少的正多边形等边三角形来计数 ...
- 【译】宣布三项新的高级 Visual Studio 订阅者福利
Visual Studio 订阅(无论是专业版还是企业版)提供的不仅仅是软件使用权:这是一个全面的工具包,旨在显著提高您的开发能力和职业发展.这些订阅每年可以为您节省数千美元,提供各种服务,从每月用于 ...
- .NET 中高效 Excel 解决方案 MiniExcel
前言 MiniExcel 是一个用于 .NET 平台的轻量级.高性能的库,专注于提供简单易用的 API 来处理 Excel 文件.以下是 MiniExcel 的特点总结: 轻量级与高效:MiniExc ...
- Codeforces Round 953 (Div. 2)
Codeforces Round 953 (Div. 2) 闲来无事水题解. A . B . C 显然 \(k\) 是偶数.考虑 \(k\) 的上界,\(p_{1}=n,p_{n}=1\),产生 \( ...