什么应该与Java对象同步

时间:2012-03-19 19:56:52

标签: java concurrency synchronized

假设您有2个或更多共享对象A的线程。

对象A里面有一个列表,其中包含另一个对象B

对象A.     名单          对象B

现在线程修改/读取对象B

问题是,应该同步什么? 对象A,因为它们都访问它,或对象B,因为它是他们读取/修改的内容

我无法在任何地方找到问题的答案。

提前致谢

2 个答案:

答案 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>();
    ...

阅读Java concurrent programming tutorial会有所帮助。

答案 1 :(得分:0)

如果您通过其中一种方法修改对象B,那么您应该使该方法(或执行写入的部分)同步。