ReadWriteLock vs. ConcurrentHashMap

I've been reviewing the concurrency package and going through Goetz's JCIP book.
I've learned that ConcurrentHashMap is optimized for when the most common operation is a read of a value that already exists. Also, the ReadWriteLock interface seems appropriate for when the number of readers exceeds the number of writers.
I'd like to maintain a table of 100 trucks and their current x/y positions on a map. I've got one writer thread to that table that will periodically update some subset of the table. I have at least one, and maybe several readers of the table that will do a periodic read.
ConcurrentHashMap seems like it would do the job, but I'm also considering Map with ReentrantReadWriteLock (which also seems to be optimized for reads as the common operation).
Could anyone provide advantages/disadvantages of either approach or alternatives that I haven't mentioned?
Thanks for any info.

Using a concurrent class is good for updates that are not transactional in nature, so to speak. The class guarantees the data structure will not be corrupted by multiple threads accessing it, but this isn't always enough. For example, if you need to make multiple changes to the data in such a way that will be seen as an atomic change by other threads, then your lock needs to be for the duration of the entire change, not just individual changes.
Here's a really contrived example: Let's say you stored the truck coordinates separately in your map (e.g., instead of getting position by requesting "TruckA", you would get "TruckA-XCoordinate" and "TruckA-YCoordinate" separately). When you update a truck's position, you want to update both coordinates in such a way that no reader will ever see only one coordinate updated (such as the new X value, and the old Y value). This requires an external lock on the structure while both values are updated.

Similar Messages

  • Best practice for ConcurrentHashMap use?

    Hi All, would the following be considered "best practice", or is there a better way of doing the same thing? The requirement is to have a single unique "Handler" object for each Key:
    public class HandlerManager {
        private Object lock = new Object();
        private Map<Key,Handler> map = new ConcurrentHashMap<Key,Handler>();
        public Handler getHandler(Key key) {
            Handler handler = map.get(key);
            if (handler == null) {
                synchronized(lock) {
                    handler = map.get(key);
                    if (handler == null) {
                        handler = new Handler();
                        map.put(key, handler);
            return handler;
    }Clearly this is the old "double-checked-locking" pattern which didn't work until 1.5 and now only works with volatiles. I believe I will get away with it because I'm using a ConcurrentHashMap.
    Any opinions? is there a better pattern?
    Thanks,
    Huw

    My personal choice would be to use the reliable "single-checked-locking" pattern:
        public Handler getHandler(Key key) {
            synchronized(lock) {
                Handler handler = map.get(key);
                if (handler == null) {
                    handler = new Handler();
                    map.put(key, handler);
                return handler;
        }But I'm afraid the Politically Correct way of doing it nowadays looks as ugly as this:
    class HandlerManager {
        private Map<Key,Handler> map = new HashMap<Key,Handler>();
        private final Lock readLock;
        private final Lock writeLock;
        public HandlerManager() {
            ReadWriteLock lock = new ReentrantReadWriteLock();
            readLock = lock.readLock();
            writeLock = lock.writeLock();
        public Handler getHandler(Key key) {
            Handler handler = null;
            readLock.lock();
            try {
                handler = map.get(key);
            } finally {
                readLock.unlock();
            if (handler == null) {
                writeLock.lock();
                try {
                    handler = map.get(key);
                    if (handler == null) {
                        handler = new Handler();
                        map.put(key, handler);
                finally {
                    writeLock.unlock();
            return handler;
    }

  • Java.util.concurrent.ConcurrentHashMap

    All,
    I prefer to use the java.util.ConcurrentHashMap over a Hashtable but there are some points regarding this structure that are not very clear to me.
    From java.util.concurrent: Class ConcurrentHashMap:
    "A hash table supporting full concurrency of retrievals and adjustable expected concurrency for updates. This class obeys the same functional specification as Hashtable, and includes versions of methods corresponding to each method of Hashtable.
    *+However, even though all operations are thread-safe, retrieval operations do not entail locking, and there is not any support for locking the entire table in a way that prevents all access. This class is fully interoperable with Hashtable in programs that rely on its thread safety but not on its synchronization details. Iterators are designed to be used by only one thread at a time."+ *
    Also from: Java API: Package java.util.concurrent, we read:
    "The "Concurrent" prefix used with some classes in this package is a shorthand indicating several differences from similar "synchronized" classes. For example java.util.Hashtable and Collections.synchronizedMap(new HashMap()) are synchronized. But ConcurrentHashMap is "concurrent". A concurrent collection is thread-safe, but not governed by a single exclusion lock. In the particular case of ConcurrentHashMap, it safely permits any number of concurrent reads as well as a tunable number of concurrent writes. "Synchronized" classes can be useful when you need to prevent all access to a collection via a single lock, at the expense of poorer scalability. In other cases in which multiple threads are expected to access a common collection, "concurrent" versions are normally preferable. And unsynchronized collections are preferable when either collections are unshared, or are accessible only when holding other locks."
    Based on above, is this correct of I say:
    When using a structure like Hashtable, all the methods or operations are synchronized,
    meaning if one thread is accessing the Hashtable (by get(), put(),... or other methods on this structure), it owns the lock and all other threads will lock out until the thread that owns the lock releases the lock; which means only one thread can access the hash table at a time; which can cause performance issues.
    We need to use a synchronized block or method only of two threads modify a "shared resource", if they do not modify a shared resource, we do not need to use the synchronization.
    On the other hand, the methods of ConcurrentHashMap are not synchronized; so multiple threads can access the ConcurrentHashMap at the same time. But isn't the ConcurrentHashMap itself the "shared resource" that threads are accessing? Should we use it only if the threads are reading from map and not writing to it? And then if threads also write to the structure, then it looks like its better to not to use the ConcurrentHashMap, rather use the regular HashMap with the synchronized wrapper?
    Any help is greatly appreciated.

    We need to use a synchronized block or method only of two threads modify a "shared resource", if they do not modify a shared resource, we do not need to use the synchronization. Actually, you need to synchronize access to the shared resource for both readers and writers. If one thread is updating an unsynchronized HashMap, and a concurrent thread tries to read that map, it may be in an inconsistent state. When synchronizing on the map, the reader will be blocked until the writer completes.
    What you don't need to do is prevent multiple readers from accessing the map, if there's no writer. However, a synchronized map or HashTable will single-thread reads as well as writes.
    On the other hand, the methods of ConcurrentHashMap are not synchronized; so multiple threads can access the ConcurrentHashMap at the same time. But isn't the ConcurrentHashMap itself the "shared resource" that threads are accessing? No, it's actually synchronized at a finer level. Without getting into the details of HashMap implementation, an object's hashcode is used to identify a linked list of hashmap entries. The only time that you have a concurrency issue is when a reader and writer are accessing the same list. So the ConcurrentHashMap locks only the list that's being updated, and allows readers (and writers!) to access the other bucket lists. Plus, it allows two readers to proceed concurrently.

  • ConcurrentHashMap VS. HashTable

    Hi all,
    I need to use a thread-safe map and am not sure if I can safely use java.util.concurrent.ConcurrentHashMap instead of HashTable w/o external synchronization. The Java docs says:
    "A hash table supporting full concurrency of retrievals and adjustable expected concurrency for updates. This class obeys the same functional specification as Hashtable, and includes versions of methods corresponding to each method of Hashtable.
    *+However, even though all operations are thread-safe, retrieval operations do+ +not+ +entail locking, and there is+ +not+ +any support for locking the entire table in a way that prevents all access. This class is fully interoperable with+ **+Hashtable+** +in programs that rely on its thread safety but not on its synchronization details.+*
    *+Retrieval operations (including+ **+get+**+) generally do not block, so may overlap with update operations (including+ **+put+** +and+ **+remove+**+). Retrievals reflect the results of the most recently+ +completed+ +update operations holding upon their onset. For aggregate operations such as+ **+putAll+** +and+ **+clear+**+, concurrent retrievals may reflect insertion or removal of only some entries. Similarly, Iterators and Enumerations return elements reflecting the state of the hash table at some point at or since the creation of the iterator/enumeration+*.
    They do +not+ throw [ConcurrentModificationException|http://java.sun.com/javase/6/docs/api/java/util/ConcurrentModificationExceptio
    *+However, iterators are designed to be used by only one thread at a time.+*"
    I do use iterators on my map; and it will be used by many threads at the same time; so does that mean I need to externally "synchronize" my map?
    The parts in bold and italic made me not sure about using the ConcurrentHashMap...

    JavaFunda wrote:
    So can anybody give a example where we hashtable can not be replace by ConcusrrentHashMapPersonally, other than Peter's first suggestion, I can't think of a single one. I believe that EJP's post (other than line 3) was aimed at why you might prefer a HashMap ( not Hashtable) over CHM; and he's dead right.
    Winston

  • ConcurrentHashMap shared with 2 threads

    Hello Guys,
    I would be really happy if you could help me.
    I am having a main program which creates a ConcurrentHashMap and adds key-value pairs to this CHM.
    A second thread should iterate over this CHM at the same time and delete expired entries (right now all values mod5 = 0). Unfortunately every time the second thread finds an expired entry, it deletes all elements saved in this list.
    What can I do to make this work?
    Here the code of my testing program:
    //### MAIN #####
    import java.util.HashMap;
    import java.util.concurrent.ConcurrentHashMap;
    public class Main {
          * @param args
         public static void main(String[] args) {
              ConcurrentHashMap<Integer, TestContainer> chm = new ConcurrentHashMap<Integer, TestContainer>();
              TestContainer tc = new TestContainer(0,0);
              CleanerThread cleanT = new CleanerThread(chm);
              cleanT.start();
              for(int i = 0; i < 100; i++){
                   tc.index = i;
                   tc.value = (int) (Math.random()*10);
                   System.out.println("1 Thread: Creating ["+tc.index+"="+tc.value+"]");
                   chm.put(i, tc);
                   System.out.println(chm.size());
                   try {
                        Thread.sleep(1000);
                   } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
    //### Thread ###
    import java.util.Iterator;
    public class CleanerThread extends Thread {
         ConcurrentHashMap<Integer, TestContainer> chm;
         Iterator it;
         public CleanerThread(ConcurrentHashMap<Integer, TestContainer> chm) {
              this.chm = chm;
         @Override
         public void run() {
              TestContainer tc;
              while (true) {
                   it = chm.values().iterator();
                   while (it.hasNext()) {
                        tc = (TestContainer) it.next();
                        if ((tc.value % 5) == 0) {
                             System.out.println("2 Thread: Removing ["+tc.index+"="+tc.value+"]");
                             it.remove();
                   try {
                        Thread.sleep(3000);
                   } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
    //### Container ###
    public class TestContainer {
         public int index;
         public int value;
         public TestContainer(int index, int value) {
              super();
              this.index = index;
              this.value = value;
    /*### Output ###
    1 Thread: Creating [0=6]
    1 Thread: Element count = 1
    1 Thread: Creating [1=9]
    1 Thread: Element count = 2
    1 Thread: Creating [2=4]
    1 Thread: Element count = 3
    1 Thread: Creating [3=2]
    1 Thread: Element count = 4
    1 Thread: Creating [4=4]
    1 Thread: Element count = 5
    1 Thread: Creating [5=5]
    1 Thread: Element count = 6
    2 Thread: Removing [5=5]
    2 Thread: Removing [5=5]
    2 Thread: Removing [5=5]
    2 Thread: Removing [5=5]
    2 Thread: Removing [5=5]
    2 Thread: Removing [5=5]
    1 Thread: Creating [6=4]
    1 Thread: Element count = 1
    1 Thread: Creating [7=6]
    1 Thread: Element count = 2
    1 Thread: Creating [8=3]
    1 Thread: Element count = 3
    1 Thread: Creating [9=0]
    1 Thread: Element count = 4
    1 Thread: Creating [10=6]
    1 Thread: Element count = 5
    1 Thread: Creating [11=4]
    1 Thread: Element count = 6
    1 Thread: Creating [12=8]
    1 Thread: Element count = 7
    1 Thread: Creating [13=9]
    1 Thread: Element count = 8
    1 Thread: Creating [14=1]
    1 Thread: Element count = 9
    1 Thread: Creating [15=8]
    1 Thread: Element count = 10
    1 Thread: Creating [16=7]
    1 Thread: Element count = 11
    1 Thread: Creating [17=3]
    1 Thread: Element count = 12
    1 Thread: Creating [18=6]
    1 Thread: Element count = 13
    1 Thread: Creating [19=3]
    1 Thread: Element count = 14
    1 Thread: Creating [20=3]
    1 Thread: Element count = 15
    1 Thread: Creating [21=4]
    1 Thread: Element count = 16
    1 Thread: Creating [22=7]
    1 Thread: Element count = 17
    1 Thread: Creating [23=3]
    1 Thread: Element count = 18
    1 Thread: Creating [24=5]
    1 Thread: Element count = 19
    1 Thread: Creating [25=8]
    1 Thread: Element count = 20
    1 Thread: Creating [26=3]
    1 Thread: Element count = 21
    1 Thread: Creating [27=9]
    1 Thread: Element count = 22
    1 Thread: Creating [28=1]
    1 Thread: Element count = 23
    1 Thread: Creating [29=1]
    1 Thread: Element count = 24
    1 Thread: Creating [30=3]
    1 Thread: Element count = 25
    1 Thread: Creating [31=5]
    1 Thread: Element count = 26
    1 Thread: Creating [32=9]
    1 Thread: Element count = 27
    1 Thread: Creating [33=2]
    1 Thread: Element count = 28
    1 Thread: Creating [34=9]
    1 Thread: Element count = 29
    1 Thread: Creating [35=2]
    1 Thread: Element count = 30
    1 Thread: Creating [36=3]
    1 Thread: Element count = 31
    1 Thread: Creating [37=8]
    1 Thread: Element count = 32
    1 Thread: Creating [38=2]
    1 Thread: Element count = 33
    1 Thread: Creating [39=9]
    1 Thread: Element count = 34
    1 Thread: Creating [40=0]
    1 Thread: Element count = 35
    1 Thread: Creating [41=7]
    1 Thread: Element count = 36
    1 Thread: Creating [42=1]
    1 Thread: Element count = 37
    1 Thread: Creating [43=1]
    1 Thread: Element count = 38
    1 Thread: Creating [44=5]
    1 Thread: Element count = 39
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    2 Thread: Removing [44=5]
    1 Thread: Creating [45=9]
    1 Thread: Element count = 1
    1 Thread: Creating [46=5]
    1 Thread: Element count = 2
    1 Thread: Creating [47=4]
    1 Thread: Element count = 3
    1 Thread: Creating [48=5]
    1 Thread: Element count = 4
    */

    Actually the session is closed as soon as I delete the key-value pair out of the map. If we get back to my example, you think all I need to do is this to have it concurrent (sounds almost to easy :) )?
    public class CleanerThread extends Thread {
         ConcurrentHashMap<Integer, TestContainer> chm;
         Iterator it;
         public CleanerThread(ConcurrentHashMap<Integer, TestContainer> chm) {
              this.chm = chm;
         @Override
         public void run() {
              TestContainer tc;
              while (true) {
                   it = chm.values().iterator();
                   while (it.hasNext()) {
                        tc = (TestContainer) it.next();
                        if ((tc.value % 2) == 0) {
                             System.out.println("2 Thread: Removing ["+tc.index+"="+tc.value+"]");
                             //it.remove();
                                            //HERE
                             chm.remove(tc.index, tc);
                                                    //or chm.remove(tc.index);
                                            //TO HERE
                   try {
                        Thread.sleep(10000);
                   } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
    }Edited by: Varox on Aug 14, 2008 5:19 AM

  • ConcurrentHashMap keySet(), entrySet(), values() thread-safety?

    hi all,
    just wondering why this code is valid? (Taken from java.util.concurrent.ConcurrentHashMap in jdk1.6.0_07):
    transient Set<K> keySet;
    transient Set<Map.Entry<K,V>> entrySet;
    transient Collection<V> values;and further down:
    public Set<K> keySet() {
        Set<K> ks = keySet;
        return (ks != null) ? ks : (keySet = new KeySet());
    public Collection<V> values() {
        Collection<V> vs = values;
        return (vs != null) ? vs : (values = new Values());
    public Set<Map.Entry<K,V>> entrySet() {
        Set<Map.Entry<K,V>> es = entrySet;
        return (es != null) ? es : (entrySet = new EntrySet());
    }Isn't there the risk of another thread reading a partially initialized keySet?

    Basically, the only state in the internal classes is their 'final' implicit reference to the parent map, and the new JMM guarantees that final fields will have correct visibility across multiple threads if the constructor is 'correctly' implemented, ie another thread that can see the constructed object will see the 'correct' values of any final fields of that object.
    I'm not quite sure you deduced this correctly from what the memory model says about final variables. It seems to me you initial hunch was actually correct -
    there is a chance of getting an improperly constructed objected when calling keySet(), values() or entrySet():
    Thread A accesses keySet(), and the compiler decides to do the assignment to the member "keySet" before it invokes the constructor.
    Now, if Thread B enters the method, it will return a reference to the partially constructed inner class object that it may try to use. You are right: there is only one implicitly final member. But where is it stated that this member is initialized up-front?
    Please look at the following excerpt from the Java language spec, in particular sentence 3. Nowhere does it say that objects containing final fields are treated any differently by the compiler with regards to re-ordering of instructions:
    "The usage model for final fields is a simple one. Set the final fields for an object in that object's constructor. Do not write a reference to the object being constructed in a place where another thread can see it before the object's constructor is finished. If this is followed, then when the object is seen by another thread, that thread will always see the correctly constructed version of that object's final fields. It will also see versions of any object or array referenced by those final fields that are at least as up-to-date as the final fields are."

  • Removing objects from a concurrentHashMap

    Hi there,
    I am trying to remove an object added to the map. But, after I remove the object using remove(key, value) the object seems to be still in the map. I am using the following functions. Please help.
      ConcurrentMap m_RequestQueue = new ConcurrentHashMap<String, QueueData>();
    public void addToRequestQueue(String id, QueueData data) throws ProvisionException
            if (isProvisionIdExist(id))
                if (null != id)
                    m_RequestQueue.putIfAbsent(id, data);
                else
                // log
            else
                throw new ProvisionException("Invalid ProvisonId or ProvisionId already exists");
    public void removeFromRequestQueue(String provId)
            if ((null != provId) && isProvisionIdExist(provId))
                QueueData data;
                if( ( data = (QueueData)m_RequestQueue.get(provId)) != null) {
                    m_RequestQueue.remove(provId, data);
    public boolean isProvisionIdExist(String provId)
            boolean retValue = false;
            if (m_RequestQueue.containsKey(provId))
                retValue = true;
            return retValue;
        }

    Oh, sorry! my bad.
    The problem is in the following function. The check should have been if (!isProvisionIdExist(id)) instead of
    if (isProvisionIdExist(id))
    public void addToRequestQueue(String id, QueueData data) throws ProvisionException
            if (!isProvisionIdExist(id))
                if (null != id)
                    m_RequestQueue.putIfAbsent(id, data);
                else
                // log
            else
                throw new ProvisionException("Invalid ProvisonId or ProvisionId already exists");
        }

  • ConcurrentHashMap scenario

    Hi all,
    Following is my scenario, let me know if ConcurrentHashMap is the soln.
    I have a cache (map) with one process say P1 (having n number of threads) does inserting into map and another process say P2 (with m number of threads) does updation of the values (that were inserted).
    Threads of P1 insert unique key / value pairs, so i thought, to do insertion faster concurrent hashmap will be better choice (with concurrency level = number of threads of P1).
    The issue is, threads of P2 get the value from the map and update the value. If, for a given key the insertion by a P1 thread and get() by P2 thread happens simultaneously, P2 thread may get the value as null....if hashtable is used, I will not get this situation as get and put are synchronized...but I will not get the performance benefit of Conccurent hashmap (during insertion)..
    This will be a large scale application with up to two million inserts tobe taken care by P1 threads(in total) and same number of updates by P2 threads.
    Please let me know your comments on this...

    harry123 wrote:
    There is no guarantee but we expect most of the times this will be the case, for other cases when the P2 gets a value first (and the corresponding insert by P1 has not been done).....
    P2 will put the value in a different cache, and its P1's responsibility to check the other cache and merge it the main cache.
    Well this solution can be applied to the issue I presented but in that we are increasing the chances of P2 not finding the value when it needs to be updated...thereby increasing number of values that go into second cache..there by putting more work on P1This is what I thought: you don't have a guarantee in either case (hashmap or concurrenthashmap). Since you're not providing a happens-before guarantee with HashMap, I don't see it as a big deal that you're not getting such a guarantee from ConcurrentHashMap either. If it is important, you need to provide that guarantee somehow, or structure your code to deal with a lack thereof.
    I'm not clear on what your end goal is; if you could elaborate, then maybe someone could provide suggestions.

  • ConcurrentHashMap()

    Hey, I had a Hashtable and I've tried to replace it with a ConcurrentHashMap but I keep getting a cannot be resolved or isn't a type error - anyone know how comes? I'm importing java.util.*; and downloaded java 1.5 ages ago.
    Thanks!
    jess

    Hey, I had a Hashtable and I've tried to replace it
    with a ConcurrentHashMap but I keep getting a cannot
    be resolved or isn't a type error - Right, because if you look at the inheritance hierarchy for ConcurrentHashMap you won't see Hashtable.
    ConcurrentHashMap extends AbstractMap extends Object. So if your variable's compile time type is a java.util.Map you can swap a Hashtable with a ConcurrentHashMap, because both classes implement that interface.
    Map map = new ConcurrentHashMap();
    // Map map = new Hashtable();It's a great argument in favor of always using the interfaces as your variable's compile time types, because that makes it possible to switch implementations as needed without affecting clients. Using concrete types locks you in.
    %

  • ConcurrentSkipListMap vs. ConcurrentHashMap

    Hi All
    I need to use a Map interface which is lockless and at the same time providing me the behavior of SortedMap. At any given instant of time there would be upto 64 threads that access this data structure. Is the ConcurrentSkipListMap the right structure for me to use ? Please advice. I could use the ConcurrentHashMap with the ctor that takes the concurrency level but it is not sorted. What would be the most efficient way to sort the ConcurrentHashMap if the ConcurrentSkipListMap doesn't work out.
    Thanks
    Avinash

    As the documentation states, the concurrent versions are designed for concurrent access. But it also notes that the correct way to answer your question is to run a test.

  • Withholding creation of value in using putIfAbsent() of ConcurrentHashMap

    Hi,
    What would be the best and thread safe implementation if I use putIfAbsent() method of ConcurrentHashMap in such a way that the value I am putting is only created if the Map does not contain the key? Our Object (used as a Map Entry value) is expensive to create and if an entry is already present do not want to create a new one. Instead of using synchronizedMap and locking the entire Map I would like to take advantages of ConcurrentHashMap.
    In the following sample I would like StringFactory.createNew() to be only called if the chm does not contain the "key" or else return the value it already has.
    public class CHMTest {
    @Test
    public void testConcurrentHashMap() {
    ConcurrentHashMap chm = new ConcurrentHashMap();
    for (int i = 0; i < 3; i++) {
    System.out.println(chm.putIfAbsent("key", StringFactory.createNew()));
    private static class StringFactory {
    public static String createNew() {
    System.out.println("Creating a new String -- Very Very expensive");
    return UUID.randomUUID().toString();
    }

    jtahlborn wrote:
    jverd wrote:
    I ususally do:
    if (!map.containsKey(x)) {
    map.putIfAbsent(x, new ExpensiveThingy());
    }It does require two tests (sort of a twist on DCL), but there's no explicit syncing necessary, and about as small performance hit as you can get.that's almost my first example (above), Yeah, I noticed that. :-) Just adding one more (albeit almost identical) option.
    however, how do you actually get the value? if you do another get() after this, you're doing more work than you need to by using containsKey().Right. I find this idiom:
    if (!map.containsKey(x)) {
      map.putIfAbsent(x, new ExpensiveThingy());
    ExpensiveThingy et = map.get(x);easiest to write and read, so that's what I usually do. I doubt the extra get is significant in most cases, and it keeps the code cleaner than with the syncing needed for the get() approach.
    (I also have the habit of using containsKey() over get() == null because a) it describes exactly what I'm trying to do and b) get() returning null can mean the key is present with a null value--even though this doesn't happen in any map I can ever recall using, and is not even allowed by ConcurrentHashMap as far as I know. Just a habit.
    EDIT:
    To expand a bit. With your first example:
    Object result = map.get(key);
    if(result == null) {
      // ... create newValue ...
      map.putIfAbsent(key, newValue);
    }We have to either sync or call get again. We can't use newValue, because we don't know that another thread hasn't come in between our null test and our put() call and put() its own entry. Using get() doesn't save anything over containsKey(), if I'm not missing something.
    Edited by: jverd on Oct 18, 2011 10:15 AM

  • HashMap is to ConcurrentHashMap as ArrayList is to ?

    In JDK 1.5, HashMap has a thread safe implementation, ConcurrentHashMap. As well, there is the corresponding interface ConcurrentMap. Does ArrayList have a thread safe implementation? If so, is there also a corresponding interface? I'm aware that I can use Collections.synchronizedList(new ArrayList<T>()) but was hoping there was something more along the lines of ConcurrentHashMap and ConcurrentMap. Thanks.

    CopyOnWriteArrayList? It really depends on your use.

  • HashMap String, ConcurrentHashMap Long, Bool concurrency , out of memory

    Need a cache as hashmap<String,ConcurrentHashMap<Long, Boolean>> for 500,000 String keys,
    each with ConcurrentHashMap of max size - million for bulk deletes (based on string key), statistics and concurrency??
    where total record count of all concurrentHashMaps is about 20 million.
    As the application is multi threaded, and we want fastest insert, update, and delete cache the only choice was a concurrentHashMap.
    Methods such as put, putIfAbsent, delete are exposed for this cache.
    For example, Is the following thread safe?
    cache = new HashMap<String, ConcurrentHashMap<Long, Boolean>>
    put(T key, value){
    ConcurrentHashMap map;
    if((map = getConcurrentHashMap(key.getStringValue())) != null){
         synchronized(cache){
              map = new ConcurrentHashMap<Long, Boolean>();
              cache.put(key.getStringValue()), map);
    map.put(key.getLongValue(), false)
    Even before we loaded a million records, we ran out of space. Why do we have so many, about 16 times the number of concurrent hash maps in heap and this is a bad sign, what other options do we have?
    12355048     593042304.00     565.5692     java.util.concurrent.locks.ReentrantLock$NonfairSync
    12355026     593041248.00     565.5682     java.util.concurrent.ConcurrentHashMap$Segment
    12355026     396169112.00     377.8163     [Ljava.util.concurrent.ConcurrentHashMap$HashEntry;
    772191     55597752     53.02215     java.util.concurrent.ConcurrentHashMap
    Thanks
    Krishna

    jtahlborn wrote:
    803891 wrote:
    :), could you read again please.
    Ofcourse, I do use putIfAbsent, but as there are many concurrent hashmaps, the only time I use synchronized is when I do not find a key without an initialized concurrentHashMap.i did read your post the first time, and it is still incorrect. the point of ConcurrentHashMap is to avoid using synchronized. besides that, your code has a timing hole if more than one thread try to access a new key for the first time. they could get 2 different sub-maps. (not to mention a logic bug). the correct way to lazy-load a ConcurrentMap (assuming that object construction for the values is cheap):
    ConcurrentHashMap<Long, Boolean> map;
    if((map = getConcurrentHashMap(key.getStringValue())) == null) {
    map = new ConcurrentHashMap<Long, Boolean>();
    ConcurrentHashMap<Long, Boolean> curMap = cache.putIfAbsebent(key.getStringValue()), map);
    if(curMap != null) {
    map = curMap;
    The good thing about my cache is 99% of the keys (String) are eagerly known. The cache is a HashMap here, so are you suggesting this should also be a ConcurrentHashMap as well, otherwise your cache.putIfAbsent will still require a lock on cache itself, which is what I did below, is there anything wrong here:
    public Boolean put(T key){
              String stringKey = key.getStringKey();
              return getLongCache(stringKey).put(key.getLongKey, true);
    all ... methods use getLongCache() first
    private ConcurrentHashMap<Long, Boolean> getLongCache(
                   String stringKey) {
              ConcurrentHashMap<Long, Boolean> longCache;
              if((longCache = cache.get(key.getStringValue())) == null) {
                   longCache = putIfAbsentLongCache(key.getStringKey);
              return longCache;
    public ConcurrentHashMap<Long, Boolean> putIfAbsentLongCache(
                   String stringKey){
              // acquire implicit client side lock as it is different from this lock
              synchronized(cache) {
                   ConcurrentHashMap<Long, Boolean> longCache;
                   if((longCache = cache.get(stringKey)) == null) {
                        longCache = new ConcurrentHashMap<Long, Boolean>();
                        cache.put(stringKey, longCache);
                   return longCache;
         }>
    No, the whole idea was to avoid the database and use it as a cache, what other alternatives do I have.i understand that. hope you are using a 64bit jvm on a box with lots o' memory. however, for most normal database scenarios, a good ORM (like hibernate) with the correct caching configured will handle the load you need. you would only need something like this for an extreme scenario, in which case you'll probably need a big box.Yeah, I did not really expect this, that is way too much memory to just setup about half a million concurrentHashMaps. But are there other choices such as writing my own map type?
    Edited by: 803891 on Oct 21, 2010 8:24 AM

  • ConcurrentHashMap's putifAbsent() method

    Hi ,
    I am trying to use ConcurrentHashMap's putifAbsent() method .
    But my requirement is that :
    The value passed to this method is a new object . I would like to avoid creating new object , when the map has the key already.
    For example:
    my code is like this .
    map.putIfAbsent(key, new Object());
    I would like to avoid creating new Object() when the key is already present in the map.
    How can I achieve this ?
    Any suggestion would be helpful.
    Tutika

    Then employ proper thread synchronization. You do know
    what the "synchronized" block is for, right? The whole point of ConcurrentHashMap is to avoid synchronizing in order to increase utilization of a multi-cpu computer.
    Thanks for your reply. Will it not give any multi
    threading issues ?
    Object x = map.get(key);
    if (x == null) // it wasn't there, so do your thing
    If 2 threads arrive at (x== null) , 2 objects will be
    created for me . I would like to avoid it .
    Map will be having only one value .but 2 objects will
    be created.The above code or putIfAbsent() will created multiple objects. You have to decide if that is really a problem. When going for concurrency in order to maximize utilization of multiple CPUs, you have to make some trade offs. If the Object being created light, it shouldn't be a problem creating multiples copies of it. You have much better concurrency than synchronizing. One will get in the map the other will just get quickly discarded.
    If it is critical that the Object not be created than you can add levels of indirection or take the concurrency hit and due synchronization as suggested by warnerja. Then you might as well not use the ConcurrentHashMap.
    One level of indirection is to create a lightweight wrapper Object that goes into the ConcurrentHashMap that will contain your real value. Compare it to the Object returned by putIfAbsent (In this case you can use the == operator). If it is the same object then create the Real value object and put it in the wrapper. Just beware that other threads may get an empty wrapper until this operation completes.
    Another thing you can do is to look at the source code of putIfAbsent and create extend ConcurrentHashMap and create another method like putIfAbsent that takes an interface that can call back on a method of that interface when a new object is needed. Something like:
    interface ObjectCreator<T> {
      T createObject();
    class MyConcurrentHashMap<K,V> extends ConcurrentHashMap {
        public V putIfAbsent(K key,ObjectCreator<V> objectCreator) {
            // This is like the regular putIfAbsent except
            // don't add objectCreater,  Add object returned by
            // objectCreator.createObject() if object is going to
            // be added to the map
    void myCode() {
      map.putIfAbsent(
          key,
          new ObjectCreator<Object>() {
            Object createObject() {
               return new Object();
      );

  • Sync on iterating thru a ConcurrentHashMap?

    i've read that synchronizing on collections while iterating thru them is tricky.
    i "think" one should normally do this:
    Map<Connection, Boolean> connPool = new HashMap<Connection, Boolean>();
    Set<Connection> connSet = map.keySet();
    Iterator it = connSet.iterator();
    syncrhonize(it) {  // correct object to synchronize on
      while(it.hasNext()) {
    }as opposed to doing this:
    Map<Connection, Boolean> connPool = new HashMap<Connection, Boolean>();
    Set<Connection> connSet = map.keySet();
    Iterator it = connSet.iterator();
    syncrhonize(connSet) {  // <-- _WRONG_ object to synchronize on
      while(it.hasNext()) {
    }now, what if i am using
    java.util.concurrent.ConcurrentHashMap
    i read the API:
    +....... However, iterators are designed to be used by only one thread at a time. ......+
    my interpretation of this is that
    if i iterate on a ConcurrentHashMap i would still need to synchronize on the Iterator (just like in a standard HashMap ), right?

    the situation is:
    i have many threads that analyze data and they retrieve from a database.
    opening a java.sql.Connection is extremely slow, so i use a Connection pool:
    ConcurrentHashMap<Connection, Boolean> connPool;
    the Boolean value is "true" if the Connection is not being used by another thread.
    for example, i might have 15 data analysis Threads and 5 Connections in the connectionPool.
    when a Thread needs to query the database, it asks for an idle Connection.
    so, i Iterate over the keySet() of the connPool Map looking for a "true" value. if i iterate thru the whole Map and do not find an
    idle Connection, i add a new Connection. (so far, there is no need for synchronizing).
    but then what i do to increase performance, because opening a new Connection is so slow, i start a background thread to create and then add a new Connection and the iteration continues in parallel. (note: an already open Connection might be released before a new Connection is created)
    once the background thread opens a new Connection, it will connPool.put(dbConn, Boolean.TRUE); while the iteration over connPool is continuing in the primary Connection pool object.

Maybe you are looking for

  • Can not restore all data/files after disk crash.

    I have a intel MacBook Pro (2008). Hard drive crashed. I replaced the drive and all is well with that. I re-installed Leopard and the Snow Leopard upgrade. Now I am trying to restore all my files/data from my external LaCie drive. All I am seeing is

  • How do I airplay to apple TV when using Cellular network?

    I want to be able to send my netflix video to my apple tv when im using the cellular network. Can this be done? I have an out of town property that I stay at sometimes and I do not have internet access there except on my iphone. So if I bring my appl

  • Incrementing a string number for date and time

    There are probably a lot of ways to do this, but I only want to use a bunch of if - else loops if I really need to. I have a date and time for input, let's say 2006-04-19 22:00. In Java, if I convert that to 3 integers (year, month, day), it will out

  • OBE-15409: Error in loading constraint information

    Hi, I'm having a problem with the Query Builder in Reports Builder. When selecting a table with any type of constraints I get the following type of error message (Emp in user scott/tiger): OBE-15409: Error in loading constraint information for EMPNO

  • After editing camera raw and export as jpeg,image becomes overexposed when view on light room..please advise.

    need some help here. don't know if i can describe this accurately. i was using lightroom previously. edit my raw file and then export in jpeg. everything appear normal as what i wanted. recently i got cs4 and started using bridge. now after i edit my