Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Synchronizing ArrayList

In ArrayList api we have:

Note that this implementation is not synchronized. If multiple threads access an ArrayList instance concurrently, and at least one of the threads modifies the list structurally, it must be synchronized externally. (A structural modification is any operation that adds or deletes one or more elements, or explicitly resizes the backing array; merely setting the value of an element is not a structural modification.) This is typically accomplished by synchronizing on some object that naturally encapsulates the list. If no such object exists, the list should be "wrapped" using the Collections.synchronizedList method.

Here what is meant by "This is typically accomplished by synchronizing on some object that naturally encapsulates the list"? How this related to concurrent modification exception?

like image 872
Beginner Avatar asked Feb 14 '23 16:02

Beginner


2 Answers

from ArrayList

This is typically accomplished by synchronizing on some object that naturally encapsulates the list. If no such object exists, the list should be "wrapped" using the Collections.synchronizedList method. This is best done at creation time, to prevent accidental unsynchronized access to the list:

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

By "naturally encapsulates" it means that if the list is a field of an object, but the list is not publically accessible suppose the following:

class ParkingLot{
   private ArrayList<Cars> spots;

   public boolean park(int spotNumber, Car car){          
       if( spots.get(spotNumber)==null){
            spot.set(spotNumber,car);
            return true;
       }
       return false;
   }
}

In this case ParkinLot would encapulate the list spot. If you were to try and call park(), you'd want to synchronize on the ParkingLot object to prevent two threads trying to park a car in the same spot at the same time.

It is related to a ConcurrentModificationException in that it prevents you from changing the list from separate threads simultaneously (by synchronizing), which could leave the list in an inconsistent state (ie Two cars parking at the same time thinking they've successfully parked).

like image 170
vandale Avatar answered Feb 17 '23 07:02

vandale


Here what is meant by "This is typically accomplished by synchronizing on some object that naturally encapsulates the list"

If you have a class which encapsulates an ArrayList then if you synchronize on the wrapper object than the underlying ArrayList will also be synchronized. e.g.

class MyClasss{

      private final ArrayList list;
      ......
      ......
      ......
 }

If you synchronize on the instance of MyClass than the underlying list is also synchronized and the all the read / write will be serialized e.g.

class MyClasss{

      private final ArrayList list;
      ......
      ......
      ......
      public void fun(){
          synchronized(this){
                list.add(....)
           }
 }

How this related to concurrent modification exception? Before answering the above question you need to understand how ConcurrentModificationException is thrown by JVM.

ConcurrentModificationException is implemented in java by checking the modification count of each Collection. Every time you do an operation it compares the modification count before doing the operation and after doing the operation.

So if you synchronize the Collection then simultaneous modification of the modification count will not happen resulting in not throwing the ConcurrentModificationException.

Hope it helps.

like image 40
Trying Avatar answered Feb 17 '23 05:02

Trying