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

发布于 2024-10-07 02:06:46 字数 1209 浏览 2 评论 0原文

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

}

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

I have a collection which guaranteed to be visible across threads. However that doesn't guarantee visibility of states of items which are stored in this collection(eg. if I have collection of StringBuilder(mutable, not thread safe) then I have to synchronize on each item in collection during write/read, right?). So, what happens when I have collection of objects which are used for guaranteeing happen-before by themselves(eg. countdownlatch). Do I need to synchronize on each item somehow when calling await/countDown? Code below roughly illustrate this dilemma:

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();
}

}

Please correct me in my assumptions, if they are wrong.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

半葬歌 2024-10-14 02:06:46

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

因此,在这种特定情况下,正如 Cameron Skinner 所说,无需同步,因为它会强制执行“先发生”的操作。

A CountDownLatch is basically a wrapper on AbstractQueuedSynchronizer whose state is a volatile int that is mutated via Unsafe.compareAndSwapInt (which is an atomic operation).

Therefore in this specific case, as Cameron Skinner said, there is no need to synchronize because it enforces that happens-before for you.

梦冥 2024-10-14 02:06:46

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

I don't believe you need to manually synchronize in this case because the latches are internally thread-safe.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文