我是否需要在保证发生的对象上进行同步?

时间:2010-12-09 02:19:36

标签: java multithreading synchronization locking thread-safety

我有一个保证跨线程可见的集合。但是,这并不能保证存储在此集合中的项目状态的可见性(例如,如果我有StringBuilder的集合(可变,而不是线程安全),那么我必须在写入/读取期间同步集合中的每个项目,对吧? )。那么,当我收集用于保证事先发生的对象(例如,倒计时)时会发生什么。在调用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();
}

}

如果他们错了,请在我的假设中纠正我。

2 个答案:

答案 0 :(得分:3)

CountDownLatch基本上是AbstractQueuedSynchronizer上的包装器,其状态是一个通过Unsafe.compareAndSwapInt变换的volatile int(这是一个原子操作)。

因此,在这种特殊情况下,正如Cameron Skinner所说,没有必要同步,因为它强制执行之前发生的事情。

答案 1 :(得分:1)

我认为在这种情况下你不需要手动同步,因为锁存器是内部线程安全的。