Java并发编程实战~并发容器

在容器领域一个容易被忽视的“坑”是用迭代器遍历容器,例如在下面的代码中,通过迭代器遍历容器 list,对每个元素调用 foo() 方法,这就存在并发问题,这些组合的操作不具备原子性。

List list = Collections.synchronizedList(new ArrayList());
Iterator i = list.iterator(); 
while (i.hasNext())foo(i.next());

正确做法是下面这样,锁住 list 之后再执行遍历操作

List list = Collections.synchronizedList(new ArrayList());
synchronized (list) {  Iterator i = list.iterator(); while (i.hasNext())foo(i.next());
} 

发容器及其注意事项
Java 在 1.5 版本之前所谓的线程安全的容器,主要指的就是同步容器。不过同步容器有个最大的问题,那就是性能差,所有方法都用 synchronized 来保证互斥,串行度太高了。因此 Java 在 1.5 及之后版本提供了性能更高的容器,我们一般称为并发容器。

并发容器虽然数量非常多,但依然是前面我们提到的四大类:List、Map、Set 和 Queue,下面的并发容器关系图,基本上把我们经常用的容器都覆盖到了。

 鉴于并发容器的数量太多,再加上篇幅限制,所以我并不会一一详细介绍它们的用法,只是把关键点介绍一下。

(一)List
List 里面只有一个实现类就是CopyOnWriteArrayList。CopyOnWrite,顾名思义就是写的时候会将共享变量新复制一份出来,这样做的好处是读操作完全无锁。

那 CopyOnWriteArrayList 的实现原理是怎样的呢?下面我们就来简单介绍一下

CopyOnWriteArrayList 内部维护了一个数组,成员变量 array 就指向这个内部数组,所有的读操作都是基于 array 进行的,如下图所示,迭代器 Iterator 遍历的就是 array 数组。

 如果在遍历 array 的同时,还有一个写操作,例如增加元素,CopyOnWriteArrayList 是如何处理的呢?CopyOnWriteArrayList 会将 array 复制一份,然后在新复制处理的数组上执行增加元素的操作,执行完之后再将 array 指向这个新的数组。通过下图你可以看到,读写是可以并行的,遍历操作一直都是基于原 array 执行,而写操作则是基于新 array 进行。

 使用 CopyOnWriteArrayList 需要注意的“坑”主要有两个方面。一个是应用场景,CopyOnWriteArrayList 仅适用于写操作非常少的场景,而且能够容忍读写的短暂不一致。例如上面的例子中,写入的新元素并不能立刻被遍历到。另一个需要注意的是,CopyOnWriteArrayList 迭代器是只读的,不支持增删改。因为迭代器遍历的仅仅是一个快照,而对快照进行增删改是没有意义的。

(二)Map
Map 接口的两个实现是 ConcurrentHashMap 和 ConcurrentSkipListMap,它们从应用的角度来看,主要区别在于ConcurrentHashMap 的 key 是无序的,而 ConcurrentSkipListMap 的 key 是有序的。所以如果你需要保证 key 的顺序,就只能使用 ConcurrentSkipListMap。

使用 ConcurrentHashMap 和 ConcurrentSkipListMap 需要注意的地方是,它们的 key 和 value 都不能为空,否则会抛出NullPointerException这个运行时异常。下面这个表格总结了 Map 相关的实现类对于 key 和 value 的要求,你可以对比学习。

 ConcurrentSkipListMap 里面的 SkipList 本身就是一种数据结构,中文一般都翻译为“跳表”。跳表插入、删除、查询操作平均的时间复杂度是 O(log n),理论上和并发线程数没有关系,所以在并发度非常高的情况下,若你对 ConcurrentHashMap 的性能还不满意,可以尝试一下 ConcurrentSkipListMap。

(三)Set
Set 接口的两个实现是 CopyOnWriteArraySet 和 ConcurrentSkipListSet,使用场景可以参考前面讲述的 CopyOnWriteArrayList 和 ConcurrentSkipListMap,它们的原理都是一样的,这里就不再赘述了。

(四)Queue
Java 并发包里面 Queue 这类并发容器是最复杂的,你可以从以下两个维度来分类。一个维度是阻塞与非阻塞,所谓阻塞指的是当队列已满时,入队操作阻塞;当队列已空时,出队操作阻塞。另一个维度是单端与双端,单端指的是只能队尾入队,队首出队;而双端指的是队首队尾皆可入队出队。Java 并发包里阻塞队列都用 Blocking 关键字标识,单端队列使用 Queue 标识,双端队列使用 Deque 标识

这两个维度组合后,可以将 Queue 细分为四大类,分别是:

1.单端阻塞队列:其实现有 ArrayBlockingQueue、LinkedBlockingQueue、SynchronousQueue、LinkedTransferQueue、PriorityBlockingQueue 和 DelayQueue。内部一般会持有一个队列,这个队列可以是数组(其实现是 ArrayBlockingQueue)也可以是链表(其实现是 LinkedBlockingQueue);甚至还可以不持有队列(其实现是 SynchronousQueue),此时生产者线程的入队操作必须等待消费者线程的出队操作。而 LinkedTransferQueue 融合 LinkedBlockingQueue 和 SynchronousQueue 的功能,性能比 LinkedBlockingQueue 更好;PriorityBlockingQueue 支持按照优先级出队;DelayQueue 支持延时出队。

 2.双端阻塞队列:其实现是 LinkedBlockingDeque。

3.单端非阻塞队列:其实现是 ConcurrentLinkedQueue。
4.双端非阻塞队列:其实现是 ConcurrentLinkedDeque。

另外,使用队列时,需要格外注意队列是否支持有界(所谓有界指的是内部的队列是否有容量限制)。实际工作中,一般都不建议使用无界的队列,因为数据量大了之后很容易导致 OOM。上面我们提到的这些 Queue 中,只有 ArrayBlockingQueue 和 LinkedBlockingQueue 是支持有界的,所以在使用其他无界队列时,一定要充分考虑是否存在导致 OOM 的隐患。
 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/496743.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

工信部:筹建全国首个区块链和分布式记账标准化技术委员会

作者:李秀琴在3.15即将来临之时,我国工信部给区块链行业又带来了一大利好消息。3月12日,工业和信息化部(以下简称工信部)在官网发布公告称,其正在就筹建全国区块链和分布式记账技术标准化技术委员会事宜开展…

Python 的 requests 库的用法

Python爬虫利器一之Requests库的用法:http://cuiqingcai.com/2556.html Python利用Requests库写爬虫(一):http://www.jianshu.com/p/e1f8b690b951 Python-第三方库requests详解:http://blog.csdn.net/shanzhizi/articl…

2018 年人工智能会怎么发展?这里有 8 个预测

来源:36氪普华永道发布了一份报告,对人工智能在2018年的发展趋势进行了研究,并做出了8项预测。人工智能非常复杂,而且发展速度很快。任何人都不可能对其未来几年的发展方向做出准确的预测。但就人工智能在2018年的发展趋势来说&am…

C 和 C++ 文件操作详解

来源:http://www.cnblogs.com/likebeta/archive/2012/06/16/2551662.html 来源:http://www.cnblogs.com/likebeta/archive/2012/06/16/2551780.html CPP 的文件操作 在C中,有一个stream这个类,所有的I/O都以这个“流”类为基础的…

redis 判断存在性_springboot + redis + 注解 + 拦截器 实现接口幂等性校验

提醒:后面有些图片模糊,请点击原文查看清晰图片一、概念幂等性, 通俗的说就是一个接口, 多次发起同一个请求, 必须保证操作只能执行一次比如:订单接口, 不能多次创建订单支付接口, 重复支付同一笔订单只能扣一次钱支付宝回调接口, 可能会多次回调, 必须处…

汽车行业最大创新仍未到来,四大力量将重塑未来汽车新纪元

来源: 资本实验室 作者:王进自第一辆福特“T”型车问世以来,汽车行业已经诞生了众多层出不穷、持续进化的创新成果。例如,制造商不断创造了新的车体风格,拓展了新的市场区隔,改进了自动换档和动力转向系…

echarts柱形图x轴y轴互换_数控机床在加工零件时,突然出现X、Y、Z轴失控?如何处理...

数控机床现在广泛应用于单品种大批量的零件加工中,由于稳定性强、精度高、效率高,取代了原来的普通机床。同时数控铣床、数控车床被大规模的配置到各产品自动化生产线上,实现了自动化无入管理。但在生产中由于数控机床的伺服系统出现故障&…

python beautiful soup库的用法

Python 爬虫利器二 之 Beautiful Soup 的用法:http://cuiqingcai.com/1319.html Beautiful Soup 4.2.0 文档:https://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html Python3 --- BeautifulSoup --- 节点选择器:https://www.…

Java并发编程实战~原子类

对于简单的原子性问题&#xff0c;还有一种无锁方案&#xff0c;先看看如何利用原子类解决累加器问题。 public class Test {AtomicLong count new AtomicLong(0);public void add10K() {int idx 0;while(idx < 10000) {count.getAndIncrement();}}} 无锁方案相对互斥锁…

著名物理学家斯蒂芬•霍金去世,他曾告诫人类要学会避免人工智能可能的风险

据多家媒体报道&#xff0c;著名的英国物理学家斯蒂芬霍金于3 月 14 日去世&#xff0c;享年 76 岁。霍金教授的孩子露西&#xff0c;罗伯特和蒂姆发表了声明确认了这一消息。斯蒂芬威廉霍金(Stephen William Hawking)&#xff0c;1942年1月8日出生于英国牛津&#xff0c;英国剑…

电路板上的插头怎么拔下来_空调插头一直不拔费电吗?实测一周竟然发现了真相!...

随着气温的不断走低&#xff0c;全国绝大部分城市已经进入了真正意义上的秋天。那么&#xff0c;经过了酷热一夏&#xff0c;你家的空调电源插头拔掉了吗? 说道空调&#xff0c;想必大家都知道这“家伙”可是耗电大户。尤其在七八月份&#xff0c;几乎都是24小时不停机在运行。…

C++ stringstream

参考&#xff1a;http://www.usidcbbs.com/read-htm-tid-1898.html 常见格式串 %% 印出百分比符号&#xff0c;不转换。 %c 整数转成对应的 ASCII 字元。 %d 整数转成十进位。 %f 倍精确度数字转成浮点数。 %o 整数转成八进位。 %s 整数转成字符串。 %x 整数转成小写十六进位…

Java并发编程实战~思维导图

#原图 System.out.println("https://www.processon.com/view/link/61a235be1efad425fd6ff5f6")

中国“脑计划”研究正在悄然布局

来源&#xff1a;中国科学报 作者&#xff1a;黄辛 作为“十三五”上海科研发展的重点&#xff0c;一张神奇的脑计划研究“地图”正在悄然加紧布局。日前&#xff0c;在教育部科技司、国家自然科学基金委员会政策局、华东师范大学主办的“交叉融合的教育科学基础研究”研讨会上…

JDBC链接SQLServer2005 Express

SQLServer2005的数据库链接的jar包可以到微软网站上去下载&#xff0c;驱动和链接字符串如下&#xff1a; 1: String driver "com.microsoft.sqlserver.jdbc.SQLServerDriver"; 2: String url "jdbc:sqlserver://localhost:1433;databaseNamepubs"; SQLS…

dnf时装预览怎么打开_DNF:史上最好看时装上线,大佬已经玩疯,全服都是真香的气息...

大家好&#xff01;我是风柜君&#xff0c;这次又是我来给大家带来DNF游戏内外的趣事&#xff0c;希望各位喜欢。DNF国服将在6月18日迎来第11周年庆&#xff0c;而在此之前&#xff0c;国服在6月6日的时候已经更新了一波周年庆预热活动。这次的更新除了普雷妮普通副本以外&…

深度解析:AWS、谷歌云、IBM Cloud和微软 Azure四巨头2018将会有哪些布局?

来源&#xff1a; IDC圈近来&#xff0c;公司规模已经不再是企业选择云服务商的重要因素&#xff0c;市场对云服务商优劣的判断有了多种标准。企业对全球一些大型云计算服务商&#xff08;例如亚马逊AWS&#xff0c;谷歌云平台&#xff0c;IBM Cloud和微软 Azure等&#xff09;…

用法 stl_C++STL 容器篇

前言上一章节主要是详细介绍了C泛型编程基础&#xff0c;不清楚的可以回顾一下哦。本章节主要针对于CSTL(标准模板类库)做个详细介绍。标准模板类库也就是别人写的模板类&#xff0c;主要内容是各种数据结构的封装&#xff0c;以及常用算法。暂时分三个章节介绍&#xff0c;本章…

超级强大的 vim 配置(vimplus)

From : http://www.cnblogs.com/highway-9/p/5984285.html From : http://www.cnblogs.com/ma6174/archive/2011/12/10/2283393.html From : http://www.cnblogs.com/youxia/p/linux002.html From : http://blog.csdn.net/namecyf/article/details/7787479 最近在重新配置Vim&a…

谷歌将屏蔽一切与加密货币相关的广告 6月正式生效

来源&#xff1a;腾讯证券北京时间3月14日下午消息&#xff0c;据外媒报道&#xff0c;谷歌开始对与加密货币相关的广告的进行打击。谷歌可持续广告业务负责人斯科特-斯宾塞&#xff08;Scott Spencer&#xff09;在接受CNBC采访时称&#xff0c;该公司正在调整与金融服务相关的…