Java 実装と読み取り/書き込みロック アルゴリズムの考え方

Java 実装と読み取り/書き込みロック アルゴリズムの考え方

問題の背景: 複数のスレッドが共有リソースへの読み取りおよび書き込みアクセスを実行します。書き込みスレッドは相互に排他的である必要があり、読み取りスレッドと書き込みスレッドは相互に排他的である必要があり、読み取りスレッドは相互に排他的である必要はありません。

以前、私は Java 5 の強化された並行機能に関する張先生の授業に参加しました。読み取り/書き込みロックの問題は、java.util.concurrent.locks の ReadWriteLock を使用すると簡単に解決できます。 ReadWriteLock がないと synchronized だけで何ができるのかと考えています。確かにその方が面倒です。

1. 張先生が教えたオブジェクト指向設計のアイデアを組み合わせて、まず書き込みメソッドと読み取りメソッドをカプセル化する共有リソースとしてビジネス クラス Business を設計します。

2. write は相互に排他的である必要があるため、 synchronized を直接定義します。

3. 読み取りは相互に排他的である必要はないため、読み取りを直接同期として定義することはできません。ただし、書き込みと読み取りは相互に排他的である必要があります。これを制御するにはどうすればよいですか? 考えられる 1 つの方法は、読み取りに synchronized(this){} を追加し、readThreads カウンターをセマフォとして定義することです。次のような状況を想定しています。

read[m]はスレッドの読み取りメソッドを表します。

write[n] 上記と同じ

1> read[m]がsynchronized(this){readThreads++;}を実行すると、write[n]が来て、write[n]は自身のsynchronizedによってブロックされます。

2> read[m]が何かを実行しているとき(この時点ではロックなし)、write[n]が来て、readThreads!=0であるため待機を余儀なくされます。

3> read[m]が終了するたびに、待機中のwrite[n]に通知されます。しかし、他の読み取りがあることがわかった場合、write[n]は再び無力に待機することしかできません。

4> readThreads==0 で、notifyAll が呼び出されると、read[m] と write[n] が CPU を奪い合います。write[n] が再度失敗すると、1> または 3> が表示されます。成功すると、次のようになります。

5> write[n]が起動して待機中にロックを占有すると、read[m]はsynchronized(this){readThreads++;}でブロックされます。

6>ブロックされたwrite[n]がロックを占有している場合、read[m]はsynchronized(this){readThreads++;}でブロックされます。

上記から、読み取りと書き込みは相互に排他的であると思われます。

4. 実装の詳細は次のとおりです。<誤りがあれば指摘してください>

  1. パッケージ通信;
  2. java.util.Randomをインポートします
  3.  
  4. 公共 クラスReadWriteLockTest {
  5.         公共 静的  void main(String[] args){
  6.                 最終的なビジネスbusiness =新しいビジネス();
  7.                   
  8.                  // 4 つのスレッドを開始します。2 つは読み取り、2 つは書き込みです。  
  9.                  ( int i = 1 ; i <= 2 ; i++)の場合{
  10.                                 新しいスレッド(新しいRunnable(){
  11.                                         公共  void実行() {
  12.                                                  ( int j = 1 ; j < 1000 ; j++)の場合{
  13. ビジネス.read();
  14.                                                         試す{
  15. スレッド.スリープ( 900 );
  16. }キャッチ(InterruptedException e) {
  17. e.printStackTrace();
  18. }
  19. }
  20. }
  21. })。始める();
  22.                                   
  23.                                 新しいスレッド(新しいRunnable(){
  24.                                         公共  void実行() {
  25. ランダム r = new Random();
  26.                                                  ( int j = 1 ; j < 1000 ; j++)の場合{
  27.                                                          int i = r.nextInt( 100 );
  28. ビジネス.write(i);
  29.                                                         試す{
  30. スレッド.スリープ( 1000 );
  31. }キャッチ(InterruptedException e) {
  32. e.printStackTrace();
  33. }
  34. }
  35. }
  36. })。始める();
  37. }
  38.                   
  39. }
  40.           
  41. }
  42. //カプセル化されたビジネスクラス 
  43. クラスビジネス{
  44.         プライベート  int data = 0 ; // 共有リソース属性 
  45.         プライベート  int readThreads = 0 ; //スレッド番号を読み取る 
  46.          //プライベートブール値 isWriting = false;  
  47.          //writeを実行するかどうかは後で判明したが、writeがロックを獲得すると、すべてのreadはsynchronized(this){}でブロックされ、waitを実行する機会はない。  
  48.         公共  void読み取り(){
  49.                 同期されたこれ){
  50.                          /*while(isWriting){
  51. 試す {
  52. これを待機します。
  53. } キャッチ (InterruptedException e) {
  54. // TODO 自動生成されたキャッチブロック
  55. e.printStackTrace();
  56. }
  57. }*/  
  58.                          //readThreads がロックされていない場合、読み取りと書き込みが相互に排他的でない可能性がわずかながら発生し、スレッドのセキュリティが損なわれます。  
  59. スレッドを読み取ります++;
  60.                           
  61. }
  62.                   
  63. System.out.println(Thread.currentThread().getName()+ "読み取り開始" );
  64. System.out.println(Thread.currentThread().getName()+ " 読み取り: " +データ);
  65. System.out.println(Thread.currentThread().getName()+ " 読み取り完了" );
  66.                           
  67.                 同期されたこれ){
  68. スレッドを読み取ります--;
  69.                         これは.notifyAll() です。
  70. }
  71. }
  72.           
  73.         公共 同期した  void書き込み( int i){
  74.                  while (readThreads != 0 ){ //読み取りが何かを行っている状態になると書き込みが来るので、まず待つ必要があります 
  75.                         試す{
  76.                                 これは.wait();
  77. }キャッチ(InterruptedException e) {
  78. e.printStackTrace();
  79. }
  80. }
  81.                  //isWriting = true;  
  82. System.out.println(Thread.currentThread().getName()+ " 書き込み開始" );
  83. データ = i;
  84. System.out.println(Thread.currentThread().getName()+ " 書き込み: " +i);
  85. System.out.println(Thread.currentThread().getName()+ " 上書き" );
  86.                  //isWriting = false;  
  87.                 これは.notifyAll() です。
  88. }
  89. }

考え:

5. 頻繁に読み取る場合、readThreads が長時間 != 0 になり、書き込みスレッドが不足します。どうすれば解決できますか?

オリジナルリンク: http://www.cnblogs.com/hottea4Goodspeed/archive/2012/03/06/2381257.html

【編集者のおすすめ】

  1. Java 開発者の生産性を向上させる 6 つのツール
  2. Java 並行性: juc エグゼキュータ フレームワークの詳細な説明
  3. Javaアプリケーションの正常なシャットダウンの設計
  4. Spock 0.6 リリース、Java テスト フレームワーク
  5. Java の深層探索: Java メモリ領域

<<:  Google のアルゴリズムが明らかに: 検索リクエストは平均 2,400 キロメートル往復移動します

>>:  A* 検索アルゴリズム (実行可能なソース コード付き)

ブログ    
ブログ    

推薦する

自動運転列車が完成しました!しかし、あなたは座る勇気がありますか?

すべてが計画通りに進めば、鉱山大手リオ・ティントの貨物列車が8月にコロラド州プエブロ近郊の線路を走り...

また鉄の飯碗が割れた!今後、これらの仕事は人工知能に置き換えられるかもしれません!

この時代に本物の鉄丼なんて存在しない!最近、広東省の高速道路で非接触型決済が導入されたというニュース...

AI対決シリーズ:あなたのレコメンデーションアルゴリズムは破られましたか?

[[408906]] Google でニュースを検索すると、検索結果にポルノ記事が大量に混ざって表...

オッペンハイマーの「彼女は消えた」!物理学界のファーストレディ、呉健雄はマンハッタン計画の重要な問題を解決した

長い待ち時間を経て、ついに『オッペンハイマー』が国内で公開される。ノーラン監督は映画の細部と品質に細...

...

...

これらの6つのヒントを活用してAIガバナンスの問題を解決しましょう

AI ガバナンスは、データ プライバシー、アルゴリズムのバイアス、コンプライアンス、倫理など、企業内...

Meili United が VALSE カンファレンスで「ファッションをグラフィックで説明」する画像アルゴリズムの体験を共有する方法

最近、第7回ビジョンと学習セミナー(VALSE)が厦門大学で成功裏に終了しました。 VALSE は ...

映画の好みを予測しますか?オートエンコーダを使用して協調フィルタリングを実装する方法

推奨システムは、協調フィルタリングを使用して、ユーザーの好み情報を収集し、特定のユーザーの興味を予測...

...

科学者たちは、人間のチームが海洋ゴミを見つけるのを助けるために人工知能を搭載したドローンを開発している

ニューアトラス誌の報道によると、海洋ゴミは、海に漂うゴミと海岸に打ち上げられるゴミの両方の形で大きな...

中国がSORAをいかにして複製したかを、中国のチームが長文の記事で解説! 996 OpenAI研究者:SoraはビデオGPT-2の瞬間です

現在、この写真は AI コミュニティで広く流布されています。さまざまな文化ビデオ モデルの誕生時期、...

X-Dreamerは2Dと3D生成のギャップを埋め、高品質のテキストから3D生成を実現します。

近年、事前学習済みの拡散モデル[1, 2, 3]の開発により、テキストから3Dコンテンツへの自動作成...

...