5 Replies Latest reply: Jan 16, 2008 9:19 AM by 807603 RSS

    Query on using Collection object in Multithreading

    807603
      All,

      I have a query on multithreading, I have a collection object-eg. HashMap which needs to be shared
      among threads, I my have 3 options

      1st option is to synchronize the method which does some manipulation on the collection object,

      2nd option is to hold a lock on that object like
      synchronized(object){
      //do some work
      }

      3rd option - to make use of class ConcurrentHashMap available in java.util.concurrent package; which claims to be
      Thread safe but also says the following in the API - They do not throw ConcurrentModificationException. However,
      iterators are designed to be used by only one thread at a time

      My queston is - how do I choose between these 3?
      I know the decison needs to be taken by keeping performance issue in mind and also the number of times the values in HashMap will be updated by the threads. Can some one explain to me when/under what circumstances do I use options 1 || 2 || 3
        • 1. Re: Query on using Collection object in Multithreading
          807603
          The HashMap API entry has the following:

          Note that this implementation is not synchronized. If multiple threads access a hash map concurrently, and at least one of the threads modifies the map structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more mappings; merely changing the value associated with a key that an instance already contains is not a structural modification.) This is typically accomplished by synchronizing on some object that naturally encapsulates the map. If no such object exists, the map should be "wrapped" using the Collections.synchronizedMap method. This is best done at creation time, to prevent accidental unsynchronized access to the map:
          • 2. Re: Query on using Collection object in Multithreading
            800322
            1 and 2 are basically the same... 3 makes the most sense because it leaves the synchronization issues to the object concerned. Just don't use the iterators multi-threadedly.

            As for the performance issues: did you do performance tests that say that this is your bottleneck?
            • 3. Re: Query on using Collection object in Multithreading
              807603
              My application has actually gone live now - after doing some load/performance testing
              and comming to the conclusion that performance is satisfactory [I am designing a SMS gateway
              that receives/buffers/stores/sends SMS]

              Initially I used Hashmap and a LinkedList to store objects in memory and I had a mixture
              of places where some times I made the entire method that modifies the LinkedList & hashmap
              synchronized and some places where I held a lock on the object alone (I wasnt too sure which to use where)

              Then upon movin to 1.5 I rechanged the the data structure to use ConcurrentLinkedQueue & ConcurrenthashMap.

              But i have places where I still hold synchronized locks over those objects (which i think is unnecessary and removing the locks may improve the performance)

              So can i come to the conclusion that classes in java.util.concurrent are all threadsafe and we can stop holding locks on the objects and let java take care of itself [or should I still hold a lock when doing structural modification] [though the APi states that a oncurrentmodificationexception will not be thrown & iterators are designed to be used by only one thread at a time]
              • 4. Re: Query on using Collection object in Multithreading
                807603
                Hmm, I also have a related question.

                What if, I have 2 functions:
                public synchronized void removeObject(Object obj) {
                  list.remove(obj); //ArrayList
                }
                
                public synchronized void addObject(Object obj) {
                  list.add(obj);
                }
                Is it possible for 2 threads to simultaniously access the list through these functions ? (1 Thread adding and 1 removing). Or would it be properly synchronized? The ArrayList used is not a concurrentList.
                • 5. Re: Query on using Collection object in Multithreading
                  807603
                  hms wrote:
                  Hmm, I also have a related question.

                  What if, I have 2 functions:
                  public synchronized void removeObject(Object obj) {
                  list.remove(obj); //ArrayList
                  }
                  
                  public synchronized void addObject(Object obj) {
                  list.add(obj);
                  }
                  Is it possible for 2 threads to simultaniously access the list through these functions ? (1 Thread adding and 1 removing). Or would it be properly synchronized? The ArrayList used is not a concurrentList.
                  Not as long as both of these methods are in the same class, and the methods are called on the same object. A synchronized method is like "synchronized (this)".

                  EDIT: I should be clearer: Given the conditions above, each thread will have exclusive access to the list, and two threads will not add/remove at the same time. Of course, you will also need to synchronize any other list access (e.g. reading).

                  Edited by: paul.miner on Jan 16, 2008 9:18 AM