java高并发编程详解 pdf_高并发编程系列:7大并发容器详解(附面试题和企业编程指南)...

不知道从什么时候起,在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锁保证线程安全。

并发容器有哪些分类

1.ConcurrentHashMap

对应的非并发容器:HashMap

目标:代替Hashtable、synchronizedMap,支持复合操作

原理:JDK6中采用一种更加细粒度的加锁机制Segment“分段锁”,JDK8中采用CAS无锁算法。

2.CopyOnWriteArrayList

对应的非并发容器: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实现

6.ConcurrentLinkedQueue

不会阻塞的队列

对应的非并发容器:Queue

原理:基于链表实现的FIFO队列(LinkedList的并发版本)

7.LinkedBlockingQueue、ArrayBlockingQueue、PriorityBlockingQueue

对应的非并发容器:BlockingQueue

特点:拓展了Queue,增加了可阻塞的插入和获取等操作

原理:通过ReentrantLock实现线程安全,通过Condition实现阻塞和唤醒

实现类:

  • LinkedBlockingQueue:基于链表实现的可阻塞的FIFO队列
  • ArrayBlockingQueue:基于数组实现的可阻塞的FIFO队列
  • PriorityBlockingQueue:按优先级排序的队列

ConcurrentHashMap的实现

73923715b018ecedd1a65ca7cf6d4e5e.png

HashMap,Hashtable与ConcurrentHashMap都是实现的哈希表数据结构,在随机读取的时候效率很高。

Hashtable实现同步是利用synchronized关键字进行锁定的,其是针对整张哈希表进行锁定的,即每次锁住整张表让线程独占,在线程安全的背后是巨大的浪费。

ConcurrentHashMap和Hashtable主要区别就是围绕着锁的粒度进行区别以及如何区锁定。

上图中,左边是Hashtable的实现方式,可以看到锁住整个哈希表;而右边则是ConcurrentHashMap的实现方式,单独锁住每一个桶(segment).ConcurrentHashMap将哈希表分为16个桶(默认值),诸如get(),put(),remove()等常用操作只锁当前需要用到的桶,而size()才锁定整张表。

原来只能一个线程进入,现在却能同时接受16个写线程并发进入(写线程需要锁定,而读线程几乎不受限制)。

所以,才有了并发性的极大提升。

高并发编程,除了并发容器,还会涉及到并发工具类:CountDownLatch等,后续将详细的介绍并发工具类,以及ConcurrentHashMap的底层实现细节,不仅要知其然,还要知其所以然,这样才能更好的掌握好高并发编程。


以上就是Java并发容器的详解,除了从编程的角度应对高并发,更多还需要从架构设计的层面来应对高并发场景,例如:Redis缓存、CDN、异步消息等,详细的内容如下。

更多高并发架构设计专题

一道多线程面试题可以区分平庸和卓越

827d9b6689a32acf0717fd2d14aa9e08.png

高并发编程,企业级编程指南

77eb7c8ef53dcd37e6f128a94bca6033.png

并发架构资料,获取方式

关注+转发后,私信关键词 【资料】即可获取!

重要的话讲两遍,转发、转发后再发私信,才可以拿到哦!


http://www.niftyadmin.cn/n/1326720.html

相关文章

python快递费用计算_Python实现快递查询

今天介绍一个19行代码就能搞定的查询快递的脚本。开发语言:Python开发环境:windowsPython3.6版本开发平台:PyCharm首先导入json以及request模块importjsonimportrequestsJSON(JavaScript Object Notation,JS对象标记)是一种轻量级的数据交换格…

为什么.class文件查看不了_Class文件结构

Class文件结构Java技术能够一直保持非常好的向后兼容性,这点Class文件结构的稳定性功不可没。Java目前已经发展到JDK14,但是class文件结构的内容,绝大部分在JDK1.2时代就已经定义好了。虽然JDK1.2的内容比较古老,但是java发展经历…

开弹幕卡顿的原因_女主播整容后开播被水友骂哭!直播间公开整容原因都怪土豪?...

董月月是虎牙的一名LOL女主播在今年八月的时候因为“龙鸣”事件在直播间下跪磕头起因是她在直播间骂那些开黄腔的人称他们是“龙鸣”有网友在直播间直接带起了节奏说她说的是“农民”而董月月替自己解释表示自己说的是“龙鸣”但是董月月解释不成反而让更多的水友带起了节奏觉得…

jquery ajax post提交数据_高级前端:详解手写原生Ajax的实现

点击上方“前端印象”,选择“设为星标”第一时间关注技术干货!对于Ajax,肯定很多小伙伴都听过甚至用过了,那么没听过的也不用着急,本文会对Ajax进行讲解,其次,一定还有一些人只用过JQuery封装好…

servletcheckbox选中和未选中判断_NBA五大100%命中率大战,皆为上个世纪,姚明未上榜...

100%命中率对于一个篮球运动员而言,难度是可想而知的。我们平时在户外投篮投着玩,都不敢保证自己能百发百中,更别说在比赛上,球员们往往会在高强度的对抗下进行激烈的战斗,这样一来,球员的命中率…

关于CentOS镜像下载地址

CentOS版本的不同自然镜像也不一样,那我们从哪里下载这些镜像呢?今天我给大家介绍几个我经常用的几个网站: https://wiki.centos.org/Download #CentOS的开源镜像网站 https://opsx.alibaba.com/mirror #阿里巴巴开源镜像网站 http://mirrors…

uiautomation遍历windows所有窗口_窗口崩溃 如何才能不“株连”

在Windows 10 1903版(以及更新版系统)出现之前,如果在Windows 10中打开多个窗口后,若其中一个窗口出现锁死,别的窗口可能也会跟着不能操作,包括任务栏上的所有按钮都无法点击了,一个窗口的问题让其他窗口跟着受累。新版…

String数组转List的三种方式

数组转List是经常会遇到的需求,但是转换的时候也需要注意,否则会出现异常。 数组转集合的方法一般有三种: 第一种: 通过Arrays.asList(array)进行转换,通过该方式将数组转成集合之后,不能对集合进行增删…