4

If I have something like this snippet-

public List<E> list =  Collections.synchronizedList(new ArrayList<E>());

then if I do some operations inside a method -

boolean absent = !list.contains(x);             // Statement 1
if(absent)                                      // Statement 2
    list.add(x);                                // Statement 3

do I need to wrap the above statements inside synchronized(list){ ... } to make the operations atomic?

Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122
Farhan stands with Palestine
  • 13,890
  • 13
  • 58
  • 105
  • 2
    I don't think this question is a multiple of the one given in the link. This one asks synchronizing blocks of code on the list, while the other one is about synchronizing single method calls. Even their answers are different (necessary for this, not necessary for the other). – uoyilmaz Sep 27 '16 at 10:37
  • 1
    @uoyilmaz It is a canonical covering the usecase of using `synchronized` with the `synchronizedList` method. And [answers](http://stackoverflow.com/a/9468329/1743880) cover this point also: *If the block performs multiple operations on the list [...] then the synchronized is not superfluous* – Tunaki Sep 27 '16 at 10:43

3 Answers3

3

do I need to wrap the above statements inside synchronized(list){ ... } to make the operations atomic?

Yes otherwise your List could be modified elsewhere in your code within the time window you call contains and add which could cause race condition issues.

It makes me thing then what is the use of Collections.synchronizedList?

Collections.synchronizedList makes your List thread safe such that you can modify it concurrently but still all method calls are executed atomically. In the case above you call contains and add that you have to execute atomically because otherwise if elsewhere we call add the result of contains could be out dated which would lead to a race condition issue. The only way to prevent race condition issues is to use a synchronize block on the same object monitor which is list in your case.

Nicolas Filotto
  • 43,537
  • 11
  • 94
  • 122
  • It makes me think then what is the use of Collections.synchronizedList? – Farhan stands with Palestine Sep 27 '16 at 10:35
  • @ShirgillFarhanAnsari Assume two threads calling remove() in parallel. If your underlying list isn't synchronized, funny things would happen. The point is to prevent problems when **independent** changes to the sync'ed list happen in parallel. You are talking about a set of calls that "belong together"! – GhostCat Sep 27 '16 at 10:37
  • 1
    Thanks for your help. I happened to see your profile. You just like me thought that it is JEE. It never is/was JEE. Its JavaEE as I was corrected by the Web Application Specialist BalusC (JSF 2.3 Expert Group member)for this. – Farhan stands with Palestine Sep 27 '16 at 10:52
2

Yes, synchronized list makes method calls atomic, but you need to synchronize access if you want to make multiple statements atomic (e.g. when iterating over the list etc.).

uoyilmaz
  • 3,035
  • 14
  • 25
1

Correct. Theoretically, anything can happen between your statements 1 and 3; thus: if you want them to happen "atomic"; then you need some way of turning them into a "single transaction".

Using synchronized(list) is a reasonable way to get there.

GhostCat
  • 137,827
  • 25
  • 176
  • 248