問題タブ [reentrantreadwritelock]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
java - Java ReentrantReadWriteLocks - 読み取りロック時に書き込みロックを安全に取得する方法は?
現在、コードでReentrantReadWriteLockを使用して、ツリーのような構造でアクセスを同期しています。この構造は大きく、一度に多くのスレッドによって読み取られ、その小さな部分が時々変更されるため、読み書きのイディオムにうまく適合しているようです。この特定のクラスでは、読み取りロックを書き込みロックに昇格できないことを理解しています。そのため、Javadocs に従って、書き込みロックを取得する前に読み取りロックを解放する必要があります。以前、再入不可のコンテキストでこのパターンをうまく使用したことがあります。
しかし、私が見つけたのは、永久にブロックしないと書き込みロックを確実に取得できないということです。読み取りロックは再入可能であり、実際にそのように使用しているため、単純なコード
再入可能に読み取りロックを取得した場合、ブロックできます。ロックを解除するための各呼び出しは、保持カウントを減らすだけであり、ロックは保持カウントがゼロになったときにのみ実際に解放されます。
最初はあまりうまく説明できなかったと思うので、これを明確にするために編集してください-このクラスには組み込みのロックエスカレーションがなく、読み取りロックを解放して書き込みロックを取得するだけでよいことを認識しています。私の問題は、他のスレッドが何をしているかに関係なく、このスレッドが再入可能に取得した場合、呼び出しgetReadLock().unlock()
が実際にこのgetWriteLock().lock()
スレッドのロックの保持を解放しない可能性があることです。その場合、このスレッドはまだ読み取りを保持しているため、への呼び出しは永久にブロックされますロックし、それ自体をブロックします。
たとえば、次のコード スニペットは、他のスレッドがロックにアクセスせずにシングルスレッドで実行されている場合でも、println ステートメントに到達しません。
この状況を処理するための良いイディオムはありますか? 具体的には、読み取りロックを (おそらく再入可能に) 保持しているスレッドが、何らかの書き込みを行う必要があることを発見し、書き込みロックを取得するために独自の読み取りロックを「一時停止」したい場合 (他のスレッドで必要に応じてブロックして、読み取りロックの保持を解放し、その後同じ状態で読み取りロックの保持を「取得」しますか?
この ReadWriteLock の実装は再入可能になるように特別に設計されているため、ロックが再入可能に取得される可能性がある場合に、読み取りロックを書き込みロックに昇格させる賢明な方法は確かにありますか? これは、単純なアプローチが機能しないことを意味する重要な部分です。
java - JavaReentrantReadWriteLockリクエスト
Sunのドキュメントが明確ではないため、JavaのReadWriteLocks(具体的にはReentrantReadWriteLockの実装)について簡単に質問します。
書き込みロックが別のスレッドによって要求されたときに、読み取りロックがスレッドによって保持されている場合はどうなりますか?書き込みロックスレッドは、現在保持されているすべての読み取りロックが解放されるのを待つ必要がありますか?また、書き込みロックが許可されて解放されるまで、すべての新しい読み取りロック要求はブロックされますか?
ありがとう
java - ReentrantReadWriteLock の読み取りロックは、RandomAccessFile の同時読み取りに十分か
データベースファイルへの同時読み取り/書き込み要求を処理するために何かを書いています。
ReentrantReadWriteLockはうまくマッチしているように見えます。すべてのスレッドが共有RandomAccessFileオブジェクトにアクセスする場合、同時読み取りのファイル ポインターについて心配する必要はありますか? 次の例を検討してください。
getRecord() メソッドでは、複数の同時リーダーで次のインターリーブが可能ですか?
スレッド 1 -> getRecord(0)
スレッド 2 -> getRecord(1)
スレッド 1 -> 共有ロックを取得する
スレッド 2 -> 共有ロックを取得する
スレッド 1 -> レコード 0 をシークする
スレッド 2 -> レコード 1 をシークする
スレッド 1 ->ファイル ポインタでレコードを読み取ります (1)
スレッド 2 -> ファイル ポインタでレコードを読み取ります (1)
ReentrantReadWriteLock と RandomAccessFile を使用して同時実行の問題が発生する可能性がある場合、代替手段は何ですか?
java - java.util.concurrent.locks.ReentrantReadWriteLock のドキュメント
免責事項:私は Java があまり得意ではなく、C# と Java の読み取り/書き込みロックを比較して、このトピックと両方の実装の背後にある決定をよりよく理解しています。
ReentrantReadWriteLock に関する JavaDoc があります。ロックのアップグレード/ダウングレードについて次のように述べています。
- ロックのダウングレード... ただし、読み取りロックから書き込みロックへのアップグレードはできません。
また、読み取りロックから書き込みロックへの手動アップグレードを示す次の例もあります。
実際には、上記のサンプルが場合によっては正しく動作しない可能性があるということですか? 行 #1 と #2 の間にロックがなく、基になる構造が他のスレッドからの変更にさらされていることを意味します。したがって、ロックをアップグレードする正しい方法と見なすことはできませんか、それともここで何か見逃していますか?
java - ConcurrentHashMap の読み取り操作と書き込み操作を ReentrantLock でラップすることは良い方法ですか?
ConcurrentHashMap の実装では、ReentrantLock が既に使用されていると思います。そのため、ConcurrentHashMap オブジェクトへのアクセスに ReentrantLock を使用する必要はありません。そして、それは同期のオーバーヘッドを増やすだけです。コメントはありますか?
java - ReentrantReadWriteLockとブールフラグの使用
大量のデータが(バックグラウンドスレッドによって)事前に読み込まれ、いっぱいになるまで使用できないキャッシュがあります(また、頻繁に再読み込みされ、その読み込み中は使用できなくなります)。isLoaded()
これを使用するクラスがアクセス前にフラグをチェックするようにしたい。私は次のようなアクセス制御のためにReentrantReadWriteLockを使用します(簡単にするためにコードではこれを省略しています)。
今、私の他のクラスには、次のようなブロックがあります。
本当に必要try/catch
ですか?フラグがfalseに設定され、readLock try()が失敗する可能性はありますか?フラグを気にせず、例外をキャッチする必要があります(例外がスローされた場合、フラグがfalseであるかのように基本的に同じコードを実行するため)。ちょっとおかしなことをしているような気がしますが、指が上がれません。ありがとう。
java - ReentrantReadWriteLock クラスの readLock() または writeLock() メソッドによって作成された休止スレッドは、CPU サイクルを消費しますか?
私はJava 6を使用しており、Java Concurrency in Practiceを読んでいます。これらのメソッドを使用するときに、ロックを待機している休眠スレッドが休眠中に CPU サイクルを使用するかどうかを調べようとしています。誰でも知っていますか?ありがとう!
マット
java - ReentrantReadWriteLockクラスのreadLock()メソッドを使用しても安全なのはいつですか。
たとえば、ファイルから読み取るときにreadLockを使用し、ファイルに書き込むときにwriteLockを使用することが適切であることは明らかです。ただし、次のような2つの値が比較されている操作がある場合:
次に、writeLockの代わりにreadLock()を使用してこのコードをロックしても大丈夫ですか?確かに、私は何も書いていませんが、2つの値を比較しています。これは、操作が含まれるため、データを読み取るだけとは少し異なります。「i」または「j」はいつでも変更される可能性があることに注意してください。理論的には、readLock()は、writeLock()がリソースを変更していない場合にのみ前進しますが、この問題のすべての複雑さを完全には理解していない可能性があります。少し灰色の領域の可能性があるように思われるので、私はいくつかの入力を得るだろうと思いました。
みんなありがとう、
マット
java - ロック操作の待機時にスレッドが永久にブロックされる
2 フェーズ ロックの Java 実装を作成しています。そこで、リエントラント ロック (ReadWrite ロック) を使用しています。問題は、スレッドが lock.readLock.lock() または lock.writeLock().lock() を実行し、ロックが既にロックされている場合、lock.readLock().unlock を使用してロックを解除した場合でも、ロックが永久にスタックすることです。 () または lock.writeLock().unlock()。つまり、ロックを解除してもウェイターは起きないようです!!! 問題を引き起こすコードは次のとおりです。
java - ReentrantReadWriteLock-一度に多くのリーダー、一度に1人のライター?
私はマルチスレッド環境に少し慣れていないので、次の状況に最適なソリューションを考え出そうとしています。
私はデータベースからデータを1日1回午前中に読み取り、そのデータをシングルトンオブジェクトのHashMapに格納します。日中のDB変更が発生した場合にのみ呼び出されるsetterメソッドがあります(これは1日に0〜2回発生します)。
マップ内の要素を返すゲッターもあり、このメソッドは1日に数百回呼び出されます。
HashMapを空にして再作成しているときにゲッターが呼び出され、空の/不正な形式のリストで要素を見つけようとする場合が心配です。これらのメソッドを同期させると、2人のリーダーが同時にゲッターにアクセスできなくなり、パフォーマンスのボトルネックになる可能性があります。書き込みはめったに発生しないので、パフォーマンスの低下をあまり受けたくありません。ReentrantReadWriteLockを使用する場合、書き込みロックが解除されるまで、ゲッターを呼び出す人にキューを強制しますか?複数のリーダーが同時にゲッターにアクセスできるようにしますか?一度に1人のライターのみを強制しますか?
これをコーディングするのは...