2010-12-09 102 views
0

我有一個保證在線程間可見的集合。但是,這並不保證存儲在這個集合中的項目狀態的可見性(例如,如果我有StringBuilder的集合(可變的,不是線程安全的),那麼我必須在寫/讀期間同步集合中的每個項目,對吧? )。所以,當我收集用於保證發生的對象時,會發生什麼 - 之前(例如countdownlatch)。我是否需要在調用await/countDown時以某種方式同步每個項目?下面的代碼大致說明了這個兩難問題:我是否需要同步確保發生的對象?

public class SyncQuestion { 

final List<CountDownLatch> lathces = new ArrayList<CountDownLatch>(); 

SyncQuestion() { 
    lathces.add(new CountDownLatch(1)); 
} 

public static void main(String[] args) throws InterruptedException { 
    final SyncQuestion sync = new SyncQuestion(); 

    final Thread sleepingThread = new Thread() { 
     public void run() { 
      for (CountDownLatch latch : sync.lathces) { 
       try { 
        latch.await(); 
       } catch (InterruptedException e) { 
        throw new RuntimeException(e); 
       } 
      } 
     }; 
    }; 

    final Thread wakingThread = new Thread() { 
     public void run() { 
      for (CountDownLatch latch : sync.lathces) { 
       latch.countDown(); 
      } 
     }; 
    }; 

    sleepingThread.start(); 
    wakingThread.start(); 
    sleepingThread.join(); 
    wakingThread.join(); 
} 

}

請糾正我在我的假設,如果他們錯了。

回答

3

A CountDownLatch基本上是AbstractQueuedSynchronizer的包裝,其狀態是通過Unsafe.compareAndSwapInt(這是一個原子操作)發生變化的易失性int。

因此,在這個特殊情況下,正如卡梅隆斯金納所說的那樣,沒有必要同步,因爲它會強制發生 - 在此之前。

1

我不相信你需要在這種情況下手動同步,因爲鎖存器在內部是線程安全的。

+0

謝謝卡梅隆。雖然你的回答是正確的,但我接受了來自馬特的一個,因爲更詳細的解釋(真的幫助我)。 – 2010-12-09 23:51:15