2011-06-27 18 views
1

Javaマルチスレッド構成を理解しようとしていますが、ブロッキングキューの簡単な実装を記述しようとしています。ブロッキングキューインプリメンテーションでJava Notifyを正しく使用する方法

class BlockingBoundedQueue<E> 
    { 
     @SuppressWarnings("unchecked") 
     BlockingBoundedQueue(int size) 
     { 
      fSize = size; 
      fArray = (E[]) new Object[size]; 
//   fBlockingQueue = new ArrayBlockingQueue<E>(size); 
     } 

     BlockingQueue<E> fBlockingQueue; 

     public synchronized void put(E elem) 
     { 
      if(fCnt==fSize-1) 
      { 
       try 
       { 
        // Should I be waiting/locking on the shared array instead ? how ? 
        wait(); 
       } 
       catch (InterruptedException e) 
       { 
        throw new RuntimeException("Waiting thread was interrupted during put with msg:",e); 
       } 
      } 
      else 
      { 
       fArray[fCnt++]=elem; 
       //How to notify threads waiting during take() 
      } 
     } 


     public synchronized E take() 
     { 
      if(fCnt==0) 
      { 
       try 
       { 
        // Should I be waiting/locking on the shared array instead ? how ? 
        wait(); 
       } 
       catch (InterruptedException e) 
       { 
        throw new RuntimeException("Waiting thread was interrupted during take with msg:",e); 
       } 
      } 

      return fArray[fCnt--]; 
      //How to notify threads waiting during put() 
     } 
     private int fCnt; 
     private int fSize; 
     private E[] fArray; 

    } 

私はその逆PUT()からのテイク()で待機しているスレッドを通知したい:ここで私が書いたコードです。誰かがこれを行う正しい方法で私を助けてくれますか?

私はjava.utilsの実装をチェックしました。この段階で私にとっては少し複雑なConditionとReentrantLocksが使用されていました。私は完全に堅牢ではないのは大丈夫ですが(しかし正しいですが)、今のところ単純です。

ありがとうございます!

答えて

2

短い答えは、あなたがより完全な答えを今すぐコメント//How to notify threads waiting during take()

を持っているところnotifyAll()を呼び出す...読むため

参照があるさ:Java Concurrency in Practice。あなたの質問に対する答えがそこにあります。

しかし、簡単に質問に答えてください:Javaでは、スレッドは同じオブジェクトをロックし、wait()notify()を使用して状態を安全に変更することによって同期します。典型的な簡素化フローは次のとおりです。

  1. スレッドAはthread.wait()を呼び出す「行くのはOK」でない場合は、ロックオブジェクト
  2. スレッドAに​​ブロックを入力してロックが、ループ内のいくつかの条件をチェック取得しますこれは、ロックを「解放」して同じロックオブジェクトに同期した他のコードが処理できるようにするものです。
  3. スレッドBはと同じロックを取得し、スレッドAが待機している状態を変更することがあります。それはnotifyAll()を呼び出すと、スレッドAは、目を覚ますと条件を再確認し、同期について覚えておくべき

いくつかのものがある進む(あり)になります。

  • それは変更を行うことにより、一貫性のあるオブジェクトの状態を保つことについてです状態アトミック。 「原子的」とは、(複数のフィールドなどの)変更全体が保証されていることを意味します(部分的でないため、一貫性のない変更はありません)
  • これは協調型です。その州の変更を許可する条件 - あなたはwaitnotifyと同じ "件名"です。状態の各部分は、それ自身のロックオブジェクトによって保護されなければなりません。あなたが代わりにあなたが
  • 静的メソッドに必要なだけのときの、ごと電話をロックしているので、これは簡単ですが、潜在的に高価であること - private Object lock = new Object();は、ロックオブジェクトとして使用thisを同期している
  • 方法罰金だろう同期されたクラスオブジェクトをロックオブジェクトとして使用する
+0

thnkxボヘミアン説明のために..私はまだいくつかの質問をしています。どのオブジェクトがロックされているのですか? 2つの異なる方法?また、あなたがループのいくつかの条件をチェックすると言う...どの状態がループ内のスレッドチェックですか? .. notifyAllを呼び出した後、すべてのスレッドが動きますか? – codeObserver

+0

本への違法なリンクを削除し、それをクリーンなものに置き換えた@ Willに感謝します。 – Bohemian

+0

これは何らかのフィッシング攻撃かどうか疑問に思っていました:)答えは詳細でボヘミアンは評判があると思っていましたので、何らかのエラーが発生するはずです。 – codeObserver

関連する問題