Search code examples
javaconcurrencysynchronizationrace-conditionjava.util.concurrent

Please explain the race condition in this put-if-absent idiom


Consider the following code and assume that list is an synchronized List.

List list = Collections.synchronizedList(new ArrayList());

if(!list.contains(element)){
       list.add(element)
}

I know that above code fragment needs to be synchronized externally (guarded by a lock) to make it completely thread safe .Where does the race condition come in here ?


Solution

  • Imagine you have two threads

    A: if(!list.contains(element)){ // false
    B: if(!list.contains(element)){ // false
    A:     list.add(element) // add once
    B:     list.add(element) // add a second time.
    

    Of course the simple solution is to use a Set. e.g.

    Set<E> set = Collections.newSetFromMap(new ConcurrentHashMap<E, Boolean>());
    
    set.add(element);