同步访问内部对象的方法?

时间:2012-06-30 14:58:17

标签: java

假设我有以下内容:

public class Foo {
    private ReadingList mReadingList = new ReadingList();

    public ReadingList getReadingList() {
        synchronized (mReadingList) {
            return mReadingList;
        }
    }
}

如果我尝试在两个线程中修改ReadingList对象,上面的同步对我没有帮助,对吧?:

// Thread 1
foo1.getReadingList().setName("aaa");

// Thread 2
foo2.getReadingList().setName("bbb");

我是否必须包装我想要同步的每个方法:

public class Foo {
    private ReadingList mReadingList = new ReadingList();

    public synchronized void setReadingListName(String name) {
        mReadingList.setName(name);
    }

    public synchronized void setReadingListAuthor(String author) {
        mReadingList.setAuthor(author);
    }

    ...

等对于我想要暴露和同步的ReadingList的每个方法?我最终只是为ReadingList的每个方法编写包装器方法。

由于

2 个答案:

答案 0 :(得分:1)

1。您可以访问ReadingList源

如果您有权访问ReadingList对象,请将synchronized添加到ReadingList的所有方法中,如果您希望同步访问所有字段或某组setter,如果您只想将访问权交错到某些字段。

2。您无权访问ReadingList

你必须写下这样的东西:

public class Foo {
    private ReadingList mReadingList = new ReadingList();

    public void setReadingListName(String name) {
        synchronized(mReadingList) {
           mReadingList.setName(name);
        }
    }

    public void setReadingListAuthor(String author) {
        synchronized(mReadingList) {
           mReadingList.setAuthor(author);
        }
    }

    ...

3。使用通用锁定对象

根据Foo的性质以及整个事物的通用性,您可能会发现只有某个类或类在ReadingList中出现线程问题。

在这样的类中,您可以使用通用锁定对象:

public class Bar {
   Object readingListLock = new Object();

   public void someMethodThatModifiesReading() {
      synchronized(readingListLock) {
          foo.getReadingList().setName("1");
      }
   }

   public void someOtherMethodThatModifiesReading() {
      synchronized(readingListLock) {
          foo.getReadingList().setName("2");
      }
   }

   ...
}

答案 1 :(得分:1)

快速(而不是那么有效的解决方案)是在ReadingList的实现中同步ReadingList的所有方法。

寻找Reader-Writer锁以获得更有效的同步访问方式:它允许一次多次读取和单次写入。

您的第一个解决方案只能确保一个线程一次获得ReadingList,而不是其他任何东西 - 许多线程可以同时读取和修改ReadingList