2

私が次のものを持っているとしましょう:

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

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

2つのスレッドで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の各メソッドのラッパーメソッドを作成するだけになります。

ありがとう

4

2 に答える 2

1

迅速な(そしてそれほど効率的ではない解決策)は、の実装のすべてのメソッドを同期することReadingListですReadingList

アクセスを同期するためのより効率的な方法については、リーダーライターロックを探してください。これにより、一度に複数の読み取りと単一の書き込みが可能になります。

最初のソリューションでは、一度に1つのスレッドのみを取得し、それ以外は何も確認ReadingListしません。多くのスレッドが同時に読み取りと変更を行うことができますReadingList

于 2012-06-30T15:01:55.070 に答える
1

1.ReadingListソースにアクセスできます

ReadingListオブジェクトにアクセスできる場合synchronized、すべてのフィールドへの同期アクセスが必要な場合はReadingListのすべてのメソッドに追加し、特定のフィールドへのアクセスのみをインターリーブしたい場合は特定のセッターグループに追加します。

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の性質と、この全体の汎用性によっては、特定の1つまたは複数のクラスのみが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");
      }
   }

   ...
}
于 2012-06-30T15:01:22.657 に答える