同步容器将所有对容器状态的访问都串行化,以实现线程安全性。这种方式的缺点是严重降低并发性。Java 5.0提供了多种并发容器来改进同步容器的性能。如ConcurrentHashMap代替同步且基于散列的Map,CopyOnWriteArrayList,用于在遍历操作主要操作的情况下代替同步的List,同时提供了一些常见的符合操作,如,若没有则添加,替换及有条件删除等。Java 6引入了ConcurrentSckipListMap和ConcurrentSkipListSet,分别代替同步的SortedMap和SortedSet。

  通过并发容器来代替同步容器,可以极大地提高性能并降低风险。

ConcurrentHashMap

  同步容器类在执行每个操作期间都持有锁。在一些操作,如HashMap.get和List.contains,可能包含大量工作:遍历散列表或链表来查找特定的对象,必须调用equals方法。这将花费大量时间,而其他线程在这段时间将不能访问该容器。
  ConcurrentHashMap 也是基于散列的Map,并不是将每个方法都在同一个锁上同步并使每次只有一个线程访问容器,而是使用一种粒度更细的加锁机制来实现各大程度的共享,这种机制称为分段锁。任意数量的读取线程可以并发的访问Map,执行读取操作的线程和执行写入操作的线程可以并发的访问Map,并且一定数量的写入线程可以并发的修改Map。
  类似的并发容器增强了同步容器,它们提供的迭代器不会抛出ConcurrentModeficationException,因此不需要在迭代过程加锁。 ConcurrentHashMap 返回的迭代器具有弱一致性,可以容忍并发的修改,当创建迭代器时会遍历已有的元素,并可以在迭代器被构造后将修改操作反映给容器。
  尽管并发容器改进很多,但是还存在需要权衡的因素,对于需要在整个map上计算的方法,如size和isEmpty,这些方法返回的结果可能已经过期了,实际上只是估计值。虽然这个看上去存在很大问题,实际上在并发环境下,这些方法作用很小,因为他们的值一直在变。这些操作的弱化换取其他更重要操作的性能优化,如get,put,containsKey和remove等。
  与Hashtable和synchronizedMap相比, ConcurrentHashMap有着更多的优势及更少的劣势,因此在大多数情况下使用 ConcurrentHashMap代替同步Map能进一步提高代码的可伸缩性。只有需要加锁Map进行独占访问时才应该放弃 ConcurrentHashMap。
  由于 ConcurrentHashMap不能被加锁来执行独占访问,因此无法使用客户端加锁建立新的原子操作,但是一些常见的复合操作已经实现为原子操作。

CopyOnWriteArrayList

  CopyOnWriteArrayList 用于替代同步List,在某些情况下提供更好的并发性能。并且迭代期间不需要加锁或者复制。线程安全性在于,“写入时复”制,每次修改时都会创建并重新发布一个新的容器副本。“写入时复制”容器的迭代器保留一个指向底层基础数组的引用,这个数组位于迭代器的起始位置,由于不会被修改,因此同步时只需确保数组内容的可见性。多个线程可以对这个容器进行迭代。容器的迭代器返回的元素与迭代器创建时的元素完全一致。

  每当修改容器时都会复制底层数组,这需要一定的开销,特别是规模较大时。仅当迭代操作远大于修改操作时,才应该使用"写入时复制"容器。类似的还有CopyOnWriteArraySet。如用于事件通知系统,注册和注销事件的操作远少于接受事件的操作。

java并发容器的更多相关文章

  1. java 并发容器一之BoundedConcurrentHashMap(基于JDK1.8)

    最近开始学习java并发容器,以补充自己在并发方面的知识,从源码上进行.如有不正确之处,还请各位大神批评指正. 前言: 本人个人理解,看一个类的源码要先从构造器入手,然后再看方法.下面看Bounded ...

  2. Java并发编程系列-(5) Java并发容器

    5 并发容器 5.1 Hashtable.HashMap.TreeMap.HashSet.LinkedHashMap 在介绍并发容器之前,先分析下普通的容器,以及相应的实现,方便后续的对比. Hash ...

  3. Java 并发系列之六:java 并发容器(4个)

    1. ConcurrentHashMap 2. ConcurrentLinkedQueue 3. ConcurrentSkipListMap 4. ConcurrentSkipListSet 5. t ...

  4. 《Java并发编程的艺术》第6/7/8章 Java并发容器与框架/13个原子操作/并发工具类

    第6章 Java并发容器和框架 6.1  ConcurrentHashMap(线程安全的HashMap.锁分段技术) 6.1.1 为什么要使用ConcurrentHashMap 在并发编程中使用Has ...

  5. java并发容器(Map、List、BlockingQueue)

    转发: 大海巨浪 Java库本身就有多种线程安全的容器和同步工具,其中同步容器包括两部分:一个是Vector和Hashtable.另外还有JDK1.2中加入的同步包装类,这些类都是由Collectio ...

  6. java并发容器(Map、List、BlockingQueue)具体解释

    Java库本身就有多种线程安全的容器和同步工具,当中同步容器包含两部分:一个是Vector和Hashtable.另外还有JDK1.2中增加的同步包装类.这些类都是由Collections.synchr ...

  7. Java并发容器--ConcurrentHashMap

    引子 1.不安全:大家都知道HashMap不是线程安全的,在多线程环境下,对HashMap进行put操作会导致死循环.是因为多线程会导致Entry链表形成环形数据结构,这样Entry的next节点将永 ...

  8. 【java并发容器】并发容器之CopyOnWriteArrayList

    原文链接: http://ifeve.com/java-copy-on-write/ Copy-On-Write简称COW,是一种用于程序设计中的优化策略.其基本思路是,从一开始大家都在共享同一个内容 ...

  9. 14个Java并发容器,你用过几个?

    作者:acupt 前言 不考虑多线程并发的情况下,容器类一般使用ArrayList.HashMap等线程不安全的类,效率更高.在并发场景下,常会用到ConcurrentHashMap.ArrayBlo ...

随机推荐

  1. 51nod1222 最小公倍数计数 莫比乌斯反演 数学

    求$\sum_{i = 1}^{n} \sum_{j = 1}^{i} [lcm(i, j) \le n]$因为这样不好求,我们改成求$\sum_{i = 1}^{n} \sum_{j = 1}^{n ...

  2. ZJOI 2017 二试 day1 4.26

    day0,11:30熄灯,又因为在房间里太浪,空调开了28度,过了好久才成功降温,导致睡得不太好QaQ. 于是早上昏昏欲睡,也没怎么听懂(orz孙耀峰). 中午大家一致提议下午不去听课,回到房间浪了好 ...

  3. 函数式编程(1)-高阶变成(3)-sorted

    sorted 排序算法 排序也是在程序中经常用到的算法.无论使用冒泡排序还是快速排序,排序的核心是比较两个元素的大小.如果是数字,我们可以直接比较,但如果是字符串或者两个dict呢?直接比较数学上的大 ...

  4. linux设置开机自动启动

    有很多中方法,这里只取最简单的一种: 把启动命令放到/etc/rc.d/rc.local文件里这样就可以每次启动的时候自动启动服务了, 注意给rc.local执行权限

  5. [雅礼集训 2017 Day1]市场

    link 试题分析 可以容易发现此题维护的是一个数据结构,支持区间加,区间除,区间查询最大值.其实就是在$\log$级复杂度内维护除法操作. 我们发现当除数很大或者此串序列大小差不多时,我们令$a_i ...

  6. CentOS 7网络故障

    By francis_hao    Nov 2,2017   在像往常一样打开了虚拟机后,打开xshell准备连接到centos,可是连不上,发现连接的网卡没有启动,使用systemctl启动netw ...

  7. 浅谈cocosd之autorelease\retain\release的理解

    三种情况,引出问题:   1) new出来的对象需要释放,而释放时,如果有其他人引用了这个对象,再次使用这个对象时,则会出现野指针情况. ==> 于是出现了引用计数的释放管理机制. 2) 对于一 ...

  8. python学习(十一)测试和调试

    最近学习了python的错误处理和几种测试方法 1 try except 可以通过try except方式捕捉异常 try: print('try...') r = 10/0 print('resul ...

  9. win32/linux 线程 log

    原文 #include <stdio.h> #include <stdlib.h> #include <string.h> #ifdef WIN32 #includ ...

  10. Ubuntu 火狐浏览器中,鼠标选择文字被删除的解决办法

    copy from :http://blog.csdn.net/shadow066/article/details/50628019 在终端中输入命令:ibus-setup 将 “在应用程序窗口中启用 ...