Search code examples
javacollectionsconcurrenthashmap

Java Collection Framework: Some thread safe and some not?


I am learning Java collection framework (not the Concurrent Collection framework), and I came to know that some Collection implementation are thread safe and some are not.

In most of the materials what I read,all what is mentioned that xyz is thread safe and abc isn't thread safe.

But what is the logic based on which decision was taken whether to keep a given collection type (e.g., List, Set, Queue, even in Map.. ) thread safe or not?

My question is in reference to "Traditional" Collection Framework and not on Concurrent Collection Framework.

Any inputs in understanding this would be of great help.


Solution

  • Thread safety carries an overhead (although, in modern VM's, the overhead is much lower than when the collection framework was designed). So collections aren't thread safe unless it is specifically required, with the exception of the JDK1.1 collections - when they were designed, the philosophy was more like "let's leave as little room for error, at the cost of some performance".

    We have several phases in Java API evolvement.

    JDK1.1

    In version 1.1 of Java, we had the data structures Vector and Hashtable. They are completely synchronized, providing a level of thread safety.

    JDK1.2

    In version 1.2 of Java, the collections framework was introduced. None of the basic collections are thread-safe (they don't synchronize any operations) : ArrayList, LinkedList, HashMap, TreeMap and the Set implementations.

    But you can obtain a synchronized version by calling Collections.synchronizedMap, Collections.synchronizedList, etc.

    JDK1.5

    In version 1.5 of Java, the java.util.concurrent framework was introduced. They contain specialized data structured for multi-threaded use. These provide a level of thread safety.


    Note that even with synchronized collections, it is possible to introduce data races; it only means that you cannot destroy the internal structure of the collections (all the invariants of the collections will be maintained)

    For example, if you have a two-step process where you first check that the collection doesn't contain some element, and in the second step, you insert that element. If you don't provide your own synchronization for these two steps, you can get the element added twice if two threads do this at the same time.