24

クラスには以下の2つのメソッドがread()あります。write()

class Store
{

  public void write()
  {
    // write to store;
  }

  public string  read()
  {
    // read from store;
  }
}

1)Storeオブジェクトはシングルトンです。

2)Writerストアに書き込むクラスとReader、ストアから同時に読み取るいくつかのクラスがあります。

私の要件は、ライターがストアに書き込みを行っているとき、すべてのリーダーが待機する必要があるということです。つまり、制御が にある場合write()、 へのすべての呼び出しをread()ブロックする必要があります。どうすればこれを達成できますか? メソッドを試してみsynchronize(Store.class)ましたwrite()が、うまくいかないようです。

4

5 に答える 5

41

この場合の最適なオプションは、リーダー/ライター ロックを使用することです: ReadWriteLock。単一のライターが許可されますが、複数の同時リーダーが許可されるため、このタイプのシナリオでは最も効率的なメカニズムです。

サンプルコード:

class Store
{
    private ReadWriteLock rwlock = new ReentrantReadWriteLock();

    public void write()
    {
       rwlock.writeLock().lock();
       try {
          write to store;
       } finally {
          rwlock.writeLock().unlock();
       }
    }

    public String read()
    {
       rwlock.readLock().lock();
       try {
          read from store;
       } finally {
          rwlock.readLock().unlock();
       }
    }
}
于 2012-04-29T13:59:55.097 に答える
5

synchronizedが最も簡単な解決策であるため、「私にはうまくいかないようです」とはどういう意味かを説明し、おそらくそれをどのように使用したかを示してください.

より良い解決策は、リーダーへの同時アクセスも許可するため、ReentrantReadWriteLockを使用することです。

于 2012-04-29T14:01:44.130 に答える
3

メソッドがオブジェクトで同期されると、このメソッドを実行するスレッドは、同じオブジェクトで同期される別のブロック/メソッドに入ろうとする他のすべてのスレッドをブロックします。

そのため、書き込みスレッドで読み取りスレッドの読み取りを禁止する場合は、書き込みメソッドと読み取りメソッドの両方を同期する必要があります。Storeクラスで同期する理由はありません。Storeオブジェクトでの同期はより自然です。

public synchronized void write() {
  write to store;
}

public synchronized String read() {
  read from store;
}

ただし、これには (おそらく) 欠点があります。2 つのリーダー スレッドが同時に読み取ることも禁止します。これが本当に必要な場合は、ReadWriteLockを使用する必要があります。しかし、これによりコードのパフォーマンスが低下し、理解と保守が難しくなります。これが必要であると判断した場合にのみ使用します。

于 2012-04-29T14:05:54.143 に答える
0

java.util.concurrent パッケージの ReadWriteLock を使用する

于 2012-04-29T14:00:31.977 に答える