SynchronizedList multi-thread access

I have a very simple question about a SynchronizedList .

Let's say I have a synchronizedList like -

 List syncList = Collections.synchronizedList(new ArrayList<>()) 

Now my script is Thread A trying to access add() api and Thread B trying to access remove() api synchronizedList. Will Both thread access both (add and remove) api at the same time.

I believe that threads should not access api (add () and remove ()) at the same time. Please correct me if I am wrong.

+4
source share
4 answers

Will both threads have access to both (add and remove) api in at the same time.

The answer is no.

If you have the opportunity to take a look at the source code of Collections.synchronizedList(List) , you will see that the method creates an instance of a static inner class called SynchronizedList or SynchronizedRandomAccessList , depending on the type of List you are sending as an argument.

Now both of these static inner classes extend a common class called SynchronizedCollection , which supports the mutex object, on which all method operations are synchronized to

This mutex object is assigned to this , which essentially means that the mutex object is the same returned instance .

Since the add() and remove() methods are executed under

 synchronized(mutex) { } 

block, the thread that executes add (and blocks the lock on mutex ) will not allow another thread to perform remove (by placing the lock on the same mutex ), since the first one has mutex already blocked . The last thread will wait until the lock received by the former thread on mutex receives .

So yes add() and remove() are mutually exclusive

+6
source

Can you clarify what you mean by "at the same time"?

A synchronized data structure will cause one of the two threads to wait until the other completes its work. "Waiting for a lock" can be enforced at different levels of detail and can allow reading when recording is synchronized (including deletes), but the principle remains the same.

+1
source

I would solve your problem this way:

First create a list wrapper class as follows:

 public class MySyncList{ private List<String> myList; public MySyncList(){ this.myList = new ArrayList<String>(); } public synchronized void add(String elem){ this.myList.add(elem); } public synchronized void remove(String elem){ this.myList.remove(remove); } public synchronized List<String> getList(){ return this.myList; } } 

Than access to streams:

 final MySyncList list = new MySyncList(); // final so other threads can access it ExecutorService service = Executors.newFixedThreadPool(10); for(int i=0;i<20;i++){ service.execute(new Runnable(){ public void run(){ list.add("something"); list.remove("something"); } }); } service.shutDown(); while(!service.isTerminated()); List<String> finalList = list.getList(); 
0
source

Correctly, a synchronized list is completely thread safe. Thus, from the point of view of atomicity, threads will not be able to access the list at the same time. Access from different streams will occur sequentially.

-one
source

Source: https://habr.com/ru/post/1498906/


All Articles