0

I need a threadsafe arraylist like this.

public class BookingList {

  private List<Booking> bookings;

  public BookingList() {
      bookings = Collections.synchronizedList(new ArrayList<Booking>());
  }

  @Override
  public void addBooking(Booking booking)
  {
    synchronized (bookings) {
        bookings.add(booking);
    }   
  }

  @Override
  public void removeBooking(Booking booking)
  {
    synchronized (bookings) {
        bookings.remove(booking);
    }   
  }
}

According to java doc, when using Collections.synchronizedList one needs to synchronize each access to the list. I'm not sure whether my synchronized blocks will do this?

  1. Is my use of synchronized blocks equivalent to

    ...
    public synchronized void addBooking(Booking booking) {
      bookings.add(booking);
    }
    
  2. Should I use a ReentrantLock like this

    private Lock lock = new ReentrantLock();
    public void addBooking(Booking booking) {
      try {
        lock.lock;
        bookings.add(booking);
      } finally {
        lock.release();
      }
    }
    
Achrome
  • 7,773
  • 14
  • 36
  • 45
Vering
  • 907
  • 9
  • 19

2 Answers2

6

You don't need to synchronize simple operations like add or remove because this is handled internally by the implementation and this is precisely why you use them: to avoid handling the synchronization yourself

But for composite operations like iterations or multiple removal that are out of the scope of the internal synchronization you must provide your own locking mechanism.

Pragmateek
  • 13,174
  • 9
  • 74
  • 108
  • But then I have both an add method without synchronizing and a method that makes some sort of iteration. Then I only do synchronize on the iteration method. How can Java know that the synchronization of the add and iteration-method is the same? To clarify: I see that 2 different threads cannot call "add" simultaneously, but can one thread call add and the other the iteration.method? – Vering Jun 21 '13 at 07:49
  • If you synchronize on the whole list you should not have any issue: `synchronized(bookings){ // iterate ... }` because both the *add* method and your iteration will use the same lock. – Pragmateek Jun 21 '13 at 15:11
3

To answer your questions:

1:

public synchronized void addBooking(Booking booking) {
   bookings.add(booking);
}

is equivalent to

public void addBooking(Booking booking) {
   synchronized (this){
       bookings.add(booking);
   }
}

2: for your example you should not use ReentrantLock. Calling methods of a list that has been initialized with Collections.synchronizedList() is thread-safe, no further synchronized or other locking mechanisms have to be used. For the rest see @Pragmateek's answer.

Sebastian
  • 5,177
  • 4
  • 30
  • 47