Collections. Synchronized List and Sync

List<String> list = Collections.synchronizedList(new ArrayList<String>()); synchronized (list) { list.add("message"); } 

Is the "synchronized (list) {}" block really needed?

+61
java collections synchronization
Feb 27 '12 at 16:08
source share
6 answers

You do not need to synchronize how you put in your example. HOWEVER, very important, you need to synchronize the list when you repeat it (as stated in the Javadoc):

It is imperative that the user manually synchronizes the list when it repeats:

 List list = Collections.synchronizedList(new ArrayList()); ... synchronized(list) { Iterator i = list.iterator(); // Must be in synchronized block while (i.hasNext()) foo(i.next()); } 
+88
Feb 27 '12 at 16:16
source share
— -

It depends on the exact contents of the synchronized block:

  • If a block performs a single, atomic operation on a list (as in your example), synchronized is redundant.

  • If a block performs several operations on a list — and must maintain a lock over a complex operation — then synchronized not superfluous. One common example of this is list iteration.

+27
Feb 27 '12 at 16:17
source share

Source code for the Collections.synchronizedList add method:

 public void add(int index, E element) { synchronized (mutex) {list.add(index, element);} } 

So, in your example, you do not need to add synchronization.

+19
Feb 27 '12 at 16:15
source share

It is also important to note that any methods that use Iterators, such as Collections.sort (), must also be encapsulated inside a synchronized block.

+16
Oct 24 '12 at 12:20
source share

Read this Oracle Doc

It says: "It is imperative that the user manually synchronizes in the returned list when iterating over it."

+7
Jan 15 '13 at 16:37
source share

Like what others have mentioned, synchronized collections are thread-safe , but composite actions for these collections do not guarantee streams by default.

According to JCIP, common connection actions can be

  • iteration
  • navigation
  • put-if-missing
  • check act

The synchronized OP code block is not a composite action, so it makes no difference whether you add it or not.

Take an example from JCIP and modify it a bit to find out why it is necessary to protect compound actions with blocking.

There are two methods that work in the same list collection wrapped in Collections.synchronizedList

 public Object getLast(List<String> list){ int lastIndex = list.size() - 1; return list.get(lastIndex); } public void deleteLast(List<String> list){ int lastIndex = list.size() - 1; list.remove(lastIndex); } 

If the getLast and deleteLast are called simultaneously by two different threads, alternations can occur below, and getLast will throw an ArrayIndexOutOfBoundsException . Suppose the current lastIndex is 10.

Subject A (deleteLast) -> delete
Theme B (getLast) --------------------> get

Thread A remove element before the get operation in thread B. Thus, thread B still uses 10 as the lastIndex method to call the list.get method, this will lead to a simultaneous problem.

0
Nov 20 '17 at 13:42 on
source share



All Articles