我是否需要在保证发生之前的对象上进行同步?
我有一个保证跨线程可见的集合。但是,这并不能保证存储在该集合中的项目状态的可见性(例如,如果我有 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 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
CountDownLatch
基本上是AbstractQueuedSynchronizer
的包装器,其状态是通过Unsafe.compareAndSwapInt
(这是一个原子操作)进行变异的易失性 int。因此,在这种特定情况下,正如 Cameron Skinner 所说,无需同步,因为它会强制执行“先发生”的操作。
A
CountDownLatch
is basically a wrapper onAbstractQueuedSynchronizer
whose state is a volatile int that is mutated viaUnsafe.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.
我不认为在这种情况下您需要手动同步,因为锁存器在内部是线程安全的。
I don't believe you need to manually synchronize in this case because the latches are internally thread-safe.