2013-06-20 5 views
0

Мне нужен потолочный arraylist вот так.Java synchronized statement

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

Согласно Java док, при использовании Collections.synchronizedList нужно синхронизировать каждый доступ к списку. Я не уверен, будут ли мои синхронизированные блоки делать это?

  1. Является ли мое использование синхронизированных блоков эквивалентно

    ... 
    public synchronized void addBooking(Booking booking) { 
        bookings.add(booking); 
    } 
    
  2. Должен ли я использовать ReentrantLock как этот

    private Lock lock = new ReentrantLock(); 
    public void addBooking(Booking booking) { 
        try { 
        lock.lock; 
        bookings.add(booking); 
        } finally { 
        lock.release(); 
        } 
    } 
    
+0

в этом случае: да! –

+0

U может ссылаться на эту ссылку он будет решить вашу проблему [нажмите здесь] [1] [1]: http://stackoverflow.com/questions/3814325/how-to-create-synchronized-arraylist –

ответ

6

Вам не нужно синхронизировать простых операцийдобавить или удалить, поскольку это обрабатывается внутри реализации и именно поэтому вы используете их: чтобы избежать обработки синхронизации себя

Но для составных операций как итераций или множественного удаления, которые находятся вне объема внутренней синхронизации вы должны предоставить свой собственный механизм блокировки.

+0

Это имеет смысл! Спасибо ... – Vering

+0

Но тогда у меня есть как метод добавления без синхронизации, так и метод, который делает какую-то итерацию. Затем я выполняю синхронизацию только по методу итерации. Как Java может знать, что синхронизация метода add и iteration одинакова? Чтобы уточнить: я вижу, что два разных потока не могут одновременно вызвать «добавить», но может ли один поток вызвать добавить, а другой - iteration.method? – Vering

+0

Если вы синхронизируете весь список, у вас не должно быть проблем: 'synchronized (bookings) {// iterate ...}', потому что и метод * add *, и ваша итерация будут использовать одну и ту же блокировку. – Pragmateek

3

Чтобы ответить на ваши вопросы:

1:

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

эквивалентно

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

2: для примера, вы не должны использовать ReentrantLock. Методы вызова списка, который был инициализирован с помощью Collections.synchronizedList(), является потокобезопасным, далее не требуется synchronized или другие блокирующие механизмы. Для остальных см. Ответ @ Pragmateek.

+0

этот класс должен быть таким :) –

+2

True. Я изменил это. 'this.class' будет использоваться для статических методов. – Sebastian

+0

Спасибо .. Это имеет смысл. – Vering