[Java concurrent][Collections]

同步容器类

  • 同步容器类包括Vector和Hashtable,两者是早期JDK的一部分。以及一些在JDK1.2中添加的能够由Collections.synchronizedXxx等工厂方法建立的。
  • 这些类实现线程安全的方式是,将它们的状态封装起来,并对每一个公有方法都进行同步(synchronized),使得每次只有一个线程能访问容器的状态。
  • 同步容器类在一些状况下,可能须要额外的客户端加锁来保护复合操做
    eg:
    public static Object getLast(Vector list) {
      synchronized(list) {
        int lastIndex = list.size() - 1;
        return list.get(lastIndex);
      }
    }
    

    好比在迭代的时候,须要加锁,那就会严重下降并发。这时候也能够考虑经过“克隆”容器的方法。经过考虑容器的大小、操做的开销等因素来抉择。html

  • 在迭代过程当中,若是对容器进行修改就会抛出ConcurrentModificationException的异常(该异常即便是在单线程也能够抛出,即当对象直接从容器中删除而非使用Iterator.remove()时)。
    The iterators returned by the iterator method of the collections
    * returned by all of this class's "collection view methods" are
    * fail-fast: if the Hashtable is structurally modified at any time
    * after the iterator is created, in any way except through the iterator's own
    * remove method, the iterator will throw a
    * ConcurrentModificationException

Hashtable

  • An instance of Hashtable has two parameters that affect its performance: initial capacity and load factor.
    The capacity is the number of buckets in the hash table, and the initial capacity is simply the capacity at the time the hash table is created. 由于在有冲突的时候须要顺序查找。
    The load factor (default 0.75) is a measure of how full the hash table is allowed to get before its capacity is automatically increased. 
  • variables are private;
    public function are synchronized
  • 用synchronized来锁住整张表来实现线程安全,即每次锁住整张表让线程独占。

synchronizedList 

  • static function of Collections
  • Returns a synchronized (thread-safe) list backed by the specified list.
  • In order to guarantee serial access, it is critical that all access to the backing list is accomplished through the returned list.
  • 实际上就是把原生collections封装在一个SynchronizedCollection内部,这个类有一个
    final Object mutex;   // Object on which to synchronized
    其内部的方法都是相似
    public boolean contains(Object o) { synchronized(mutex) {return c.contains(o); }}

并发容器

  • 同步容器是经过将操做串行化来实现它们的线程安全性,于是严重下降了并发性。
  • Java5.0提供了多种容器来改进同步容器的性能。好比
    • 增长了ConcurrentHashMap来替代同步且基于散列的Map
    • CopyOnWriteArrayList用于在遍历操做为主要操做的状况下代替同步的List。
    • 增长了对一些常见复合操做的支持,如“若没有则添加”、替换以及有条件删除等。

java.util.concurrent

  • refer javadoc.
  • java.util.concurrent: Utility classes commonly useful in concurrent programming.

Memory Consistency Properties

  • 首先,你须要知道happens-before,能够参考link
  • The methods of all classes in java.util.concurrent and its subpackages extend these guarantees to higher-level synchronized. In particular:
    • Actions in a thread prior to placing an object into any concurrent collection happen-before actions subsequent to the access or removal of that element from the collection in another thread.
    • Actions in a thread prior to the submission of a Runnable to an Executor happen-before its execution begins. Similarly for Callables submitted to an ExecutorService.
    • Actions taken by the asynchronous computation represented by a Future happen-before actions subsequent to the retrieval of the result via Future.get() in another thread.
    • Actions prior to "releasing" synchronizer methods such as Lock.unlockSemaphore.release, and CountDownLatch.countDown happen-before actions subsequent to a successful "acquiring" method such as Lock.lockSemaphore.acquire,Condition.await, and CountDownLatch.await on the same synchronizer object in another thread.
    • For each pair of threads that successfully exchange objects via an Exchanger, actions prior to the exchange() in each thread happen-before those subsequent to the corresponding exchange() in another thread.
    • Actions prior to calling CyclicBarrier.await and Phaser.awaitAdvance (as well as its variants) happen-before actions performed by the barrier action, and actions performed by the barrier action happen-before actions subsequent to a successful return from the corresponding await in other threads.

ConcurrentHashMap

  • Hashtable存在的问题是:在每一个方法上都加锁而下降了并发。
    ConcurrentHashMap采用的solution就是使用更细粒度的加锁机制来实现更大程度的共享,即分段锁(Lock Striping)。具体的原理是:
    内部使用Segment来表示这些不一样的部分,每一个段其实就是一个小的hashtable,它们有本身的锁。只要修改操做发生在不一样的段上,就能够并发进行。【The table is internally partitioned to try to permit the indicated number of concurrent updates without contention.】
    有的方法须要跨段,好比size()和contains(),它们可能须要锁住整张表,这就须要按顺序锁定全部表,操做完毕后,又按顺序释放全部段的锁。
  • ConcurrentHashMap在线程安全地基础上提供了更好的并发写能力,可是下降了对读一致性的要求。(感受像CAP)
  • 实现上,大量利用了volatile,final,CAS(Compare and Swap)等lock-free技术来减小锁竞争对性能的影响。

Source Code

  • TBD...
相关文章
相关标签/搜索