继续浏览精彩内容
慕课网APP
程序员的梦工厂
打开
继续
感谢您的支持,我会继续努力的
赞赏金额会直接到老师账户
将二维码发送给自己后长按识别
微信支付
支付宝支付

Java多线程并发之同步容器和并发容器-第一篇

凯哥Java
关注TA
已关注
手记 109
粉丝 12
获赞 22

Java多线程并发之同步容器和并发容器-第一篇

概述

本文主要讲解在Java多线程并发开发中,集合中有哪些支持并发的的。什么是同步容器(集合),什么是并发容器(集合)?并发容器分类有哪些?每个分类都有哪些类?

本文是《凯哥分享Java并发编程之J.U.C包讲解》系列教程中的第五篇。如果想系统学习,凯哥(kaigejava)建议从第一篇开始看。

从本篇开始,我们就来讲解讲解Java的并发容器。大致思路:先介绍什么是并发容器。然后讲解list相关的、map相关的以及队列相关的。这个系列会有好几篇文章。大家最好跟着一篇一篇学。

正文开始

回顾Java中常用的容器(集合):

我们知道Java内部的容器类是集合相关的。主要包括:List接口、Map接口以及Set接口及其子类。

Collection及Map体系如下图:

http://img1.mukewang.com/5e6ee2c50001e8f508740734.jpg

 

我们常用的类关系简化版:

http://img1.mukewang.com/5e6ee2c6000100d711320703.jpg

 

我们来简单复习下Java中集合子类及数据结构:

顶级接口

二级接口

子类

数据结构

Collection

List

Arraylist

顺序结构动态数组类【数组结构】

LinkedList

链表结构



Vector

向量



Stack

栈(是Vector的子类)



Set

HashSet

哈希表结构(底层是HashMap)


Treeset

二叉树结构(红黑树)(底层treeMap)



LinkedHashSet




Map


HashMap

链表散列(一个数组和链表的结合体)

TreeMap

二叉树



Hashtable

哈希表




说明:关于hashMap是如何解决hash冲撞问题,可以详见凯哥写的:《hashMap怎么保证hash一致性的》这篇文章详细介绍了。

http://img.mukewang.com/5e6ee2e00001d97a08920589.jpg

我们知道,绝大部分常用的集合都是线程不安全的,但是也有线程安全的。

其中线程安全的类有:

List接口下的Vector【及Stack(因为stack是Vector的子类)】

Map接口下的:HashTable【及properties(因为properties是HashTable的子类)】

我们来看看为什么vector和HashTable是线程的安全的?

查看vector源码中add方法:

http://img4.mukewang.com/5e6ee30e000104d609520517.jpg

在来看看HashTable源码中put方法:

http://img.mukewang.com/5e6ee3180001afe208190395.jpg

发现了吗?无论是vector还是hashTable都是使用了Synchronized关键之修饰的。使用了互斥同步锁机制来保证线程安全性的。

在JDK 1.5版本之前,如果想要保证线程安全,使用这两个类或者使用Collections工具类的Synxxx方法来保证线程的安全。

http://img2.mukewang.com/5e6ee3230001163b07110460.jpg

同步容器:

这些使用类Synchronized关键字修饰的容器被称为:同步容器

同步容器的缺点:

但是我们知道使用互斥锁Synchronized在并发下是很影响效率的。那是因为将并行强制转换成串行的。加互斥锁后,只有等一个锁用完之后,下一个才可以接着使用。很影响效率。

在现在大数据高并发下,有没有更好的解决方案呢?当然有的,在JDK1.5版本之后,JDK内部为我们提供了一些并发容器。

并发容器

在一般情况不考虑并发和线程安全性问题的时候,我们使用非线程安全的集合效率更高,如果需要考虑线程安全,不考虑并发或者并发很小的情况下,可以使用同步容器。但是如果在高并发下,同步容器就不能使用了。可以使用并发容器。Java中并发容器在Java.util.concurrent包下。

Concurrent包下有很多并发相关的,本篇我们就来扒拉扒拉众多并发相关类中和并发容器相关的十几个类:

http://img3.mukewang.com/5e6ee3370001740a05720875.jpg

 


http://img3.mukewang.com/5e6ee33700010c5305330225.jpg

 

并发容器分类

http://img4.mukewang.com/5e6ee3500001029204130319.jpg

大致可以分以下三类:

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个数据后的比较。


打开App,阅读手记
0人推荐
发表评论
随时随地看视频慕课网APP