4

I have very basic question about the SynchronizedList.

Lets say I have synchronizedList as -

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

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

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

1
  • 2
    You are right. There is one lock and it don't matter which method you call, it is the object which is locked, not the method. Commented Aug 26, 2013 at 7:02

4 Answers 4

6

Will the Both thread able to access the Both(add and remove) api at the same time.

The answer is no.

If you get a chance to look at Collections.synchronizedList(List) source code, you see that, the method is creating the instance of a static inner class named SynchronizedList or SynchronizedRandomAccessList, depending on the type of List you send as argument.

Now both these static inner class extend a common class called SynchronizedCollection, which maintains a mutex object, on which all method operations synchronize on

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

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

synchronized(mutex) {

}

block, a thread which executes add (and aquires lock on mutex), will not allow another thread to execute remove (by aquiring lock on same mutex), since the former has already locked the mutex. The latter thread will wait until the lock obtained by former thread on mutex gets released.

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

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

Comments

1

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

A synchronized data structure will force one of the two threads to wait until the other has completed its operation. The "wait-on-lock" can be enforced at various levels of granularity, and can allow reads while synchronizing writes (including deletes), but the principle remains the same.

1 Comment

In particular, synchronizedList will prevent corruption of the List data structure but won't prevent read-update-write race conditions.
-1

i'd solve your problem in this way:

First i create a list wrapper class like this:

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 from threads:

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();

1 Comment

Huh... What's the point of rewriting a Collections.synchronizedList?
-1

That is correct, the synchronized list is fully thread safe. So in terms of atomicity the threads will not able to access the list simultaneously. The access from different threads will happen in a serial manner.

2 Comments

It's not fullly thread safe, because iterator of that list is not thread-safe.
The question was, is the list threadsafe? Yes indeed! The iterator is a NOT a part of the list. The synchronized list itself and its internal structure is fully threadsafe.

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.