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();
      }
    }
    
有帮助吗?

解决方案

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.

其他提示

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.

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top