2013-06-20 41 views
0

我需要像這樣的線程安全列表。Java同步語句

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. 是我使用synchronized塊相當於

    ... 
    public synchronized void addBooking(Booking booking) { 
        bookings.add(booking); 
    } 
    
  2. 我應該使用這樣

    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

一個ReentrantLock的你並不需要同步簡單的操作 like add刪除,因爲這是由執行內部處理,這也正是爲什麼你使用它們:爲了避免處理同步自己

複合操作迭代多個移除是出在內部同步的範圍內,您必須提供您自己的鎖定機制。

+0

這很有道理!謝謝... – Vering

+0

但是,我有一個沒有同步的add方法和一個迭代的方法。然後我只在迭代方法上進行同步。 Java如何知道add和iteration-method的同步是相同的?澄清:我看到2個不同的線程不能同時調用「add」,但是一個線程可以調用add而另一個線程可以調用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()初始化的列表的方法是線程安全的,不需要使用其他鎖定機制。其餘請參閱@ Pragmateek的答案。

+0

這個類應該是這個:) –

+2

是的。我改變了它。 'this.class'將用於靜態方法。 – Sebastian

+0

謝謝..這是有道理的。 – Vering