2010-12-09 52 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