2

Java の実装ロックでは、ロックを読み取りロックから書き込みロックにアトミックにアップグレードする方法はありません。たとえば、次のコード スニペットは失敗します。

ReentrantReadWriteLock lock = new ...

lock.readLock().lock();

boolean mustWrite = false;
// do somestuff and determine you must instead write! :-O
if(mustWrite) {
    lock.writeLock().lock();
    writeSomeStuff();
    lock.writeLock().unlock();
}
lock.readLock.unlock();

書き込みロックの取得は、すべての読み取りロックが完了するまで待機する必要があるため、リーダーが読み取っている可能性のあるデータを上書きしていないことがわかります。良くないね。したがって、回避策は次のようにすることです。

if(mustWrite) {
    lock.readLock().unlock(); // let go of read before writing
    lock.writeLock().lock();
    writeSomeStuff();
    lock.writeLock().unlock();
    lock.readLock().lock(); // get back to reading
}

しかし、これは理想的ではありません。読み取りのロックを解除して書き込みを取得する間に、誰かが行って何かを行う可能性があります。とにかく、これらの条件を再確認することはおそらく良い考えですが、それでも - それは醜いです.

通常、ロックを取得するときは、実際にロックを取得するまでコードを強制的に待機させてから、行っていることを実行します。データをいじり始める前に、ロック機構がロックを与えてくれるということだけを信頼したくはありません。

しかし、ロックが必要であることを通知したときから、実際に待機するように読み取られるまで、実行を強制的に停止する必要があるのはなぜでしょうか? たとえば、次のようなことが許可されなかった理由は次のとおりです。

lock.writeLock().notifyIntentToLock(); // puts you in line to get the write lock
                                       // everyone else will block until you both
                                       // acquire and release the lock
lock.readLock().unlock(); // proceed with the unlock so you don't deadlock
lock.writeLock().makeGoodOnIntentToLock(); // actually acquire that lock

したがって、ある意味では、現在のロック機能は、次のように両方が同時に行われていると理論化できます。

public void lock() {
    this.notifyIntentToLock();
    this.makeGoodOnIntentToLock();
}

ある種の遅延インテントのロックを許可しないようにする設計上の決定は何ですか? そのようなロックの設計には、単に私が気付いていない重大な問題がありますか?

4

1 に答える 1

0

排他ロックを取得する決定後に行う必要があるのは、次のとおりです。

  • 読み取りロックを解除し、
  • 書き込みロックを取得し、
  • 状態を再度確認する
  • 結果に基づいて、続行または救済します。

書き込みロックを取得するインテントに関しては、複数の同時インテントが存在する場合はどうなりますか? 誰が被害者になるかを確認する方法がないため、おそらくすべてのユーザーが初期条件を確認する必要があります (勝者の後にロックが付与されます)。

それだけではありません - impl です。読み取りによってメタデータが変更され、コヒーレンシ トラフィックが発生するため、RW ロックの 1 つは起動に失敗します。したがって、RW ロックは適切にスケーリングされません。

于 2014-05-26T20:45:47.147 に答える