Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Collections.unmodifiableList(list) require a lock?

I have a productList maintained in a file named Products.java

private List<String> productList = Collections.synchronizedList(new ArrayList());

Now creating a synchronized list, will ensure that operations like add/remove will have a implicit lock and I don't need to lock these operations explicitily.

I have a function exposed which returns an unmodifiableList of this list.

public List getProductList(){

 return Collections.unmodifiableList(productList);
}

In my application, various threads can call this function at the same time. So do I need to put a synchronized block when converting a List into an unmodifiable List or will this be already taken care of since I am using a sychronizedList ?

TIA.

like image 510
thedarkpassenger Avatar asked Feb 09 '16 08:02

thedarkpassenger


1 Answers

It doesn't need to be synchronized since the unmodifiable list is wrapping the synchronized one. But there's not much use for synchronizing on an unmodifiable list, other than for the purpose of iteration, which requires manual synchronization regardless:

It is imperative that the user manually synchronize on the returned list when iterating over it:

List list = Collections.synchronizedList(new ArrayList());
    ...
synchronized (list) {
    Iterator i = list.iterator(); // Must be in synchronized block
    while (i.hasNext())
        foo(i.next());
}

Failure to follow this advice may result in non-deterministic behavior.

EDIT: As Ferrybig points out, it's actually not possible to synchronize safely with the unmodifiable wrapper. You may want to consider an alternative thread-safety solution, such as CopyOnWriteArrayList.

like image 196
shmosel Avatar answered Sep 27 '22 21:09

shmosel