假设您有2个或更多共享对象A的线程。
对象A里面有一个列表,其中包含另一个对象B
对象A. 名单 对象B
现在线程修改/读取对象B
问题是,应该同步什么? 对象A,因为它们都访问它,或对象B,因为它是他们读取/修改的内容
我无法在任何地方找到问题的答案。
提前致谢
答案 0 :(得分:2)
走最简单,最安全的路线,您需要在对象层次结构中的最外层对象上进行同步,这应该以原子方式运行。
在您的示例中,您似乎需要在列表上进行同步(遗憾的是,如果没有实际代码,我无法确定您将要做什么)。
以下是示例代码:
class B {
}
class A {
private final List<B> listOfBs = new ArrayList<B>();
void add(B b) {
synchronized (listOfBs) {
listOfBs.add(b);
}
}
List<B> getSnapshot() {
List<B> copy = new ArrayList<B>();
synchronized (listOfBs) {
copy.addAll(listOfBs);
}
return copy;
}
}
请注意,您需要将列表声明为final
,以消除某些代码可能会更改对违反原子性的列表的引用的可能性:
// will make add() and getSnapshot() not mutually exclusive, thus violating atomicity of operations
...
listOfBs = new ArrayList<B>();
...
答案 1 :(得分:0)
如果您通过其中一种方法修改对象B,那么您应该使该方法(或执行写入的部分)同步。