2011-08-02 32 views
20

私はスレッドを持っています、Aにはリストがあります。リストにはいくつかのオブジェクトがあります。今私はスレッドAに何らかのメッセージを送ることができるメカニズムを設計したいと思う。2つのスレッド間の通信

Thread Aはループして実行されます(待機したりスリープしません)。 その他のスレッドBは、スレッドAにメッセージを送信し、スレッドAはすべてのキューを空にします。

スレッド間でメッセージを送信するにはどうすればよいですか?

class A extends Thread { 
    List<Object> objs = something; //Init it 
    void run() { 
     while(true) { 
      //Body which works on objects. 
      //After receiving an external message, "A" should perform some action, for example, empty objects. 
     } 
    } 
} 

編集: このようにすることはできますか?

class A extends Thread { 
    List<Object> objs = something; //Init it 
    Boolean flag = false; 

    public void setFlag(boolean value) { 
     synchronized(flag) { 
      this.flag = value; 
     } 
    } 

    public void getFlag() { 
     synchronized(flag) { 
      return this.flag; 
     } 
    } 

    void run() { 
     while(true) { 
      //Body which works on objects. 
      //After receiving an external message, A should perform some action, for example, empty objects. 
      if (getFlag == true) 
       //Empty list 
     } 
    } 
} 
+3

Javaでは、通常はスレッド間でメッセージを送信しませんが、同期オブジェクトを使用してスレッド間で値を渡します。 – toto2

+0

私の新しい編集でメソードされたインスタンス変数を同期しましたが、それは動作しますか? – akshay

+1

@akshay編集はOKです( 'if(getFlag()== true)'を除く)。 – toto2

答えて

32

メッセージオブジェクトはBlockingQueueです。他のスレッドはメッセージをキューに入れます。 while(true)ループの一部として、スレッドApollになり、到着したメッセージはすべて処理されます。コードで

class A extends Thread{ 
List<Object> objs = something ;//init it 
BlockingQueue<Message> queue = new LinkedBlockingQueue<Message>(); 
void run(){ 
    while(true){ 
     Message msg; 
     while ((msg = queue.poll()) != null) { 
     // process msg 
     } 
     // do other stuff 
    } 
    } 
} 

他のスレッドは今Aスレッドにメッセージを送信するためにqueue.put()を呼び出すことができます。

+0

キューはスレッドAのインスタンス変数です。スレッドAがスレッドAを取得しているときにスレッドBがその中にいくつかの値を追加する場合は、問題ありませんか? – akshay

+1

@akshay:(1) 'queue'は' A'のメンバーである必要はありません(私はこれをイラストとして簡単に作った)。 (2) 'BlockingQueue'はスレッドセーフなので、いずれにしても問題はありません。 – NPE

+0

:私の新しい編集で問題が解決しますか?????????? – akshay

0

単純なケースでは、インスタンス変数をスレッドAクラスに追加し、スレッドAがそのキューをクリアする必要があることを示す値をスレッドBに設定させることができます。より高度な場合、スレッドAとスレッドBの両方がアクセスできるメッセージキューを使用できます。 Bはメッセージをそこに置き、Aはそれを読んで行動するだろう。

すべての場合、変数またはキューへのアクセスは、複数のスレッドアクセスに対して適切に保護されている必要があります。

0

コード内の別の場所で呼び出すことができるクラス "A"にメソッドを追加することができます。アクセス可能な場所にクラス "A"のインスタンスへの参照を保持してください。

class A extends Thread{ 
List<Object> objs = something ;//init it 
void run(){ 
    while(true){ 
     //body which works on objs 
     //open receiving external message A should perform some action ie empty objs 
    } 
    } 
    void ChangeState() 
    { 
    //clear objs 
    } 
} 
+0

問題が発生します。私のforループではobjsを大量に使用していますが、問題が発生するのは問題ありません。 – akshay

+0

あなたの質問はスレッドAにメッセージをどのように送って、私の反応はそれを直接目標としていました。クリアする前にコード内で適切なチェック(同期)を行うと仮定しているので、スレッドセーフには入っていませんでした。 – Garvin