【问题标题】:Do I need synchronise on objects which guarantee happen-before?我是否需要对保证发生之前的对象进行同步?
【发布时间】:2010-12-09 02:19:35
【问题描述】:

我有一个保证跨线程可见的集合。但是,这并不能保证存储在此集合中的项目状态的可见性(例如,如果我有 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();
}

}

如果我的假设是错误的,请纠正我的假设。

【问题讨论】:

    标签: java multithreading synchronization locking thread-safety


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

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

      【讨论】:

      • 谢谢卡梅伦。虽然你的回答是正确的,但我接受了马特的一个,因为有更详细的解释(真的对我有帮助)。
      猜你喜欢
      • 2013-07-04
      • 1970-01-01
      • 1970-01-01
      • 2012-09-26
      • 2017-07-06
      • 1970-01-01
      • 1970-01-01
      • 2013-12-06
      • 2015-08-10
      相关资源
      最近更新 更多