3

I have an ArrayList and I manipulate it ONLY within a synchronized block, should I use Collections.synchronizedList too? Example:

List list = Collections.synchronizedList(new ArrayList());    
// versus List list = new ArrayList();    
synchronized(list) {
      // my code
}
1
  • Only one will suffice. Use only synchronizedList Commented Mar 13, 2014 at 16:22

3 Answers 3

1
  • If you only access your list within synchronized blocks, you don't need synchronizedList()

  • If you only access your list using elementary operations (add(), remove(), etc) and invocations of these operations don't depend on each other (i.e. atomicity is not an issue), you can use only synchronizedList() without explicit synchronized blocks

  • If you want to be able to invoke elementary operations without synchronized blocks, but also have compound operations (including iteration) that should be atomic, you need both synchronizedList() and synchornized blocks for compound operations

Sign up to request clarification or add additional context in comments.

3 Comments

Not-elementary operations are just iterations? I always and only see these examples, but not others, so, "just blocks for iterations"?
There can be compound operations that should be atomic too, such as if (!list.contains(...)) list.add(...)
@Tatanan, "Not elementary" means, any sequence of operations that temporarily leaves your data in an inconsistent/invalid/illegal state. The classic example is a program that takes money out of one bank account and deposits it into another. There is an instant, in-between the withdrawal and the deposit when the books are not correct. If an auditor thread happens to look at the two accounts during that instant, it would report a violation. Putting those two operations into a synchronized block makes them an atomic unit, and would prevent the auditor from seeing the accounts in that state.
1

Just use the synchronized declaration, no need for the explicit synchronized block:

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

The only way to change the contents of the list is by invoking add or remove, which is now decorated with synchronized versions of those methods thanks to this declaration.

1 Comment

I thought the block was necessary for iterations, sorting and so on. My doubt was actually only the declaration, if in case I put all my code wrapped, I would need to declare the list as synchronized.
1

Using an explicit synchronized block and using Collections.synchronizedList(new ArrayList()) will work equivalently, with respect to mutual exclusion. However, if you must iterate over the list returned by the call to Collections, you must explicitly synchronize on that list externally anyway, per the java spec (sorry, SO won't let me link to it here).

Another thing to consider is overhead. Collections.synchronizedList(List orig) creates a new object that controls access to the original list implementation. Depending on how often you plan to make this call, and how many different ways you access the original list object, you may be better off synchronizing it externally.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.