java并发容器

  同步容器将所有对容器状态的访问都串行化,以实现线程安全性。这种方式的缺点是严重降低并发性。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。如用于事件通知系统,注册和注销事件的操作远少于接受事件的操作。

时间: 2024-10-05 06:17:16

java并发容器的相关文章

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

转发: 大海巨浪 Java库本身就有多种线程安全的容器和同步工具,其中同步容器包括两部分:一个是Vector和Hashtable.另外还有JDK1.2中加入的同步包装类,这些类都是由Collections.synchronizedXXX工厂方法.同步容器都是线程安全的,但是对于复合操作,缺有些缺点: ① 迭代:在查觉到容器在迭代开始以后被修改,会抛出一个未检查异常ConcurrentModificationException,为了避免这个异常,需要在迭代期间,持有一个容器锁.但是锁的缺点也很明显

java并发容器CopyOnWriteArrayList 使用场景和内部实现分析

java并发容器CopyOnWriteArrayListCopyOnWriteArrayList顾名思义,当数组有变化时重新建立一个新的数组 其设计是对于线程安全容器Vector使用中出现问题的一种解.在Vector容器中,当需要执行复合操作例如://代码1 class Observable { private List<Observer> observers=new Vector<Observer>(); public void addObserver(){...} public

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

Java库本身就有多种线程安全的容器和同步工具,当中同步容器包含两部分:一个是Vector和Hashtable.另外还有JDK1.2中增加的同步包装类.这些类都是由Collections.synchronizedXXX工厂方法. 同步容器都是线程安全的,可是对于复合操作.缺有些缺点: ① 迭代:在查觉到容器在迭代開始以后被改动,会抛出一个未检查异常ConcurrentModificationException,为了避免这个异常,须要在迭代期间,持有一个容器锁.可是锁的缺点也非常明显.就是对性能的

java并发容器(Map、List、BlockingQueue)详解

Java库本身就有多种线程安全的容器和同步工具,其中同步容器包括两部分:一个是Vector和Hashtable.另外还有JDK1.2中加入的同步包装类,这些类都是由Collections.synchronizedXXX工厂方法.同步容器都是线程安全的,但是对于复合操作,缺有些缺点: ① 迭代:在查觉到容器在迭代开始以后被修改,会抛出一个未检查异常ConcurrentModificationException,为了避免这个异常,需要在迭代期间,持有一个容器锁.但是锁的缺点也很明显,就是对性能的影响

Java并发指南14:Java并发容器ConcurrentSkipListMap与CopyOnWriteArrayList

原文出处http://cmsblogs.com/ 『chenssy』 到目前为止,我们在Java世界里看到了两种实现key-value的数据结构:Hash.TreeMap,这两种数据结构各自都有着优缺点. Hash表:插入.查找最快,为O(1):如使用链表实现则可实现无锁:数据有序化需要显式的排序操作. 红黑树:插入.查找为O(logn),但常数项较小:无锁实现的复杂性很高,一般需要加锁:数据天然有序. 然而,这次介绍第三种实现key-value的数据结构:SkipList.SkipList有着

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

5 并发容器 5.1 Hashtable.HashMap.TreeMap.HashSet.LinkedHashMap 在介绍并发容器之前,先分析下普通的容器,以及相应的实现,方便后续的对比. Hashtable.HashMap.TreeMap 都是最常见的一些 Map 实现,是以键值对的形式存储和操作数据的容器类型. Hashtable 是早期 Java 类库提供的一个哈希表实现,本身是同步的,不支持 null 键和值,由于同步导致的性能开销,所以已经很少被推荐使用. HashMap 是应用更加

【Java并发工具类】Java并发容器

前言 Java并发包有很大一部分都是关于并发容器的.Java在5.0版本之前线程安全的容器称之为同步容器.同步容器实现线程安全的方式:是将每个公有方法都使用synchronized修饰,保证每次只有一个线程能访问容器的状态.但是这样的串行度太高,将严重降低并发性,当多个线程竞争容器的锁时,吞吐量将严重降低.因此,在Java 5.0版本时提供了性能更高的容器来改进之前的同步容器,我们称其为并发容器. 下面我们先来介绍Java 5.0之前的同步容器,然后再来介绍Java 5.0之后的并发容器. Ja

第六章 Java并发容器和框架

ConcurrentHashMap的实现原理与使用 ConcurrentHashMap是线程安全且高效的hashmap.本节让我们一起研究一下该容器是如何在保证线程安全的同时又能保证高效的操作. 为什么要使用ConcurrentHashMap 在并发编程中使用HashMap可能导致程序死循环.而使用线程安全的HashTable效率又非常低下,基于以上两个原因,便有了ConcurrentHashMap的登场机会. (1)线程不安全的HashMap 在多线程环境下,使用HashMap进行put操作会

死磕Java并发-----J.U.C之Java并发容器:ConcurrentHashMap

HashMap是我们用得非常频繁的一个集合,但是由于它是非线程安全的,在多线程环境下,put操作是有可能产生死循环的,导致CPU利用率接近100%.为了解决该问题,提供了Hashtable和Collections.synchronizedMap(hashMap)两种解决方案,但是这两种方案都是对读写加锁,独占式,一个线程在读时其他线程必须等待,吞吐量较低,性能较为低下.故而Doug Lea大神给我们提供了高性能的线程安全HashMap:ConcurrentHashMap. ConcurrentH