现在的位置: 首页 > 综合 > 正文

Synchronized collections vs Concurrent collections

2018年01月26日 ⁄ 综合 ⁄ 共 2779字 ⁄ 字号 评论关闭

In my talk earlier this week , on "Parallel Programming Made easier - Fork Join", I briefly mentioned about the differences between collections in the context of  Program shared data. In this blog entry, I am outlining the difference between old "Synchronized
collections" and "concurrent collections"and the benefits.

What is a Synchronised collection?

Synchronised collections are the "thread safe" Collections introduced by earlier Java versions(1.2 thru 1.4), which addresses synchronization by making all the public methods of the collection "Synchronized".

Any compound operation needs to be supported with "client side Locking"

Example for a compound operation is any operation , that has "check and do", say "AddLast" element, which would first check/aquire the Size and then add the last element.
Even though both the operations, are protected by synchronised keyword, in between these operations, there is a possibility of a add/Remove operation, which can alter the
size.

A remove operation in between Getsize() and Add()  can hence cause AddLast () to throw "OutofBound" Exception,
A add operation in between Getsize() and Add() can cause AddLast to add an entry before Last, and hence not performing the intended function.

There can also be trickier places, where such compound operations could be hidden and is difficult to notice.

I hv taken this snippet from Brian goetz book ,  "Java Concurrency in practice" book. (which by the way is the bible for every programmer in modern times. Please hold a copy of it and read it and keep it with you, if you have
not by now. )

public class HiddenIterator {
    @GuardedBy("this")
    private final Set<Integer> set = new HashSet<Integer>();

    public synchronized void add(Integer i) { set.add(i); }
    public synchronized void remove(Integer i) { set.remove(i); }

    public void addTenThings() {
        Random r = new Random();
        for (int i = 0; i < 10; i++)
            add(r.nextInt());
        System.out.println("DEBUG: added ten elements to " + set);
   }
}

Even though this at the outset looks like completely synchronised , it is
NOT.

Please notice the last system.out.println.., this is actually a iterator, because the collection "set" is being iterated by
toString() method for preparing message to print.

Concurrent Collections:

5.0 Concurrent collections like ConcurrentHashMap are designed for concurrent access from Multiple threads. Instead of synchronizing every method on a common lock, restricting access to a single thread at a time, it uses a finer-grained locking mechanism called
lock striping .For example, the implementation of ConcurrentHashMap uses an array of 16 locks, each of which guards 1/16 of the hash buckets; bucket N is guarded by lock N mod 16. Assuming the hash function provides reasonable spreading characteristics and
keys are accessed uniformly, this should reduce the demand for any given lock by approximately a factor of 16. It is this technique that enables ConcurrentHashMap to support up to 16 concurrent writers

Iteration intensive collections like CopyOnWriteList and concurrentMaps also offer support to Compound operations like put-if-absent, replace, and conditional remove.
 which was absent in the synchronised collection as explained in the code snippet above.

【上篇】
【下篇】

抱歉!评论已关闭.