Search code examples
javaconcurrencyjava.util.concurrentcopy-on-write

Does casting a CopyOnWriteArrayList to a List cause it to lose its concurrency guaranties?


The above (title) is my main concern. And the case is

public class MyClass{
  CopyOnWriteArrayList<Stuff> min;
  ...
  public List<Stuff> get(){
    return min;
  }
}

Is the resulting List obtained from get() a liability? Does it affect what happens to min or is it its own copy? So for example, if I am iterating over the result of get() what's the effects?

Also while we are at it, how about the opposite? If I do

List<Stuff> stuffs = new ArrayList<Stuff>();
addABunchOfItems(stuffs);
CopyOnWriteArrayList safeStuff = (CopyOnWriteArrayList) stuffs;

What's the status of safeStuff and stuffs after the third line, concerning concurrency supports?


Solution

  • This:

    CopyOnWriteArrayList safeStuff = (CopyOnWriteArrayList) stuffs;
    

    will not work, it will raise a compile error; an ArrayList is not a CopyOnWriteArrayList.

    As to "casting" a CopyOnWriteArrayList to a List, in fact you "don't", since CopyOnWriteArrayList implements the List interface.

    Which means it respects the List contract; but internally, it is still a CopyOnWriteArrayList and no, concurrency guarantees are not lost. In fact you'll initiate one using:

    final List<Whatever> list = new CopyOnWriteArrayList<>();
    

    Note that while there are no dedicated contracts (interfaces) for concurrent implementations of List or Set, there is one for Maps: ConcurrentMap. Which does not mean you are forced to use, for instance:

    final ConcurrentMap<Whatever> map = new ConcurrentHashMap<>();
    

    if you do not need access to the specific methods of ConcurrentMap.