Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is the use of Collections.synchronizedList() method? It doesn't seem to synchronize the list

I am trying to add String values to an ArrayList using two threads. What I want is that while one thread is adding the values the other thread should not interfere so I have used the Collections.synchronizedList method. But it appears that if I don't explicitly synchronize on an object the adding is done in an unsynchronized way.

Without explicit synchronized block:

public class SynTest {     public static void main(String []args){         final List<String> list=new ArrayList<String>();         final List<String> synList=Collections.synchronizedList(list);         final Object o=new Object();         Thread tOne=new Thread(new Runnable(){              @Override             public void run() {                 //synchronized(o){                 for(int i=0;i<100;i++){                     System.out.println(synList.add("add one"+i)+ " one");                 }                 //}             }          });          Thread tTwo=new Thread(new Runnable(){              @Override             public void run() {                 //synchronized(o){                 for(int i=0;i<100;i++){                     System.out.println(synList.add("add two"+i)+" two");                 }                 //}             }          });         tOne.start();         tTwo.start();     } } 

The output that I got is:

true one true two true one true two true one true two true two true one true one true one... 

With the explicit synchronized block uncommented I'm stopping the interference from the other thread while adding. Once the thread has acquired the lock it is executing until it is finished.

sample output after uncommenting the synchronized block:

true one true one true one true one true one true one true one true one... 

So why is the Collections.synchronizedList() not doing the synchronization?

like image 766
Fullstack Guy Avatar asked Dec 02 '16 11:12

Fullstack Guy


People also ask

What is the use of collections synchronizedList?

The synchronizedList() method of java. util. Collections class is used to return a synchronized (thread-safe) list backed by the specified list. In order to guarantee serial access, it is critical that all access to the backing list is accomplished through the returned list.

Which collection methods are not synchronized?

ArrayList, LinkedList, HashSet,LinkedHashset and TreeSet in Collection Interface and HashMap,LinkedHashMap and Treemap are all non-synchronized.

What is the use of synchronized method?

Synchronized methods enable a simple strategy for preventing thread interference and memory consistency errors: if an object is visible to more than one thread, all reads or writes to that object's variables are done through synchronized methods.


1 Answers

A synchronized list only synchronizes methods of this list.

It means a thread won't be able to modify the list while another thread is currently running a method from this list. The object is locked while processing method.

As an example, Let's say two threads run addAllon your list, with 2 different lists (A=A1,A2,A3 and B=B1,B2,B3) as parameter.

  • As the method is synchronized, you can be sure those lists won't be merged randomly like A1,B1,A2,A3,B2,B3

  • You don't decide when a thread handover the process to the other thread. Each method call has to fully run and return before the other one could run. So you can either get A1,A2,A3,B1,B2,B3 or B1,B2,B3,A1,A2,A3 (As we don't know which thread call will run first).

In your first piece of code, both threads runs on the same time. And both try to add an element to the list. You don't have any way to block one thread except the synchronization on the add method so nothing prevent thread 1 from running multiple add operation before handing over the process to thread 2. So your output is perfectly normal.

In your second piece of code (the uncommented one), you clearly state that a thread completely lock the list from the other thread before starting the loop. Hence, you make sure one of your thread will run the full loop before the other one could access the list.

like image 96
jhamon Avatar answered Sep 28 '22 05:09

jhamon