2011-08-03 13 views
1

私は着信メッセージを処理するアプリケーションで作業しています。私はJavaマルチスレッドに堪能ではなく、私はあなたの助け、人々に頼んでいます。次のアプリの構造に間違いはありますか?可能なロック/パフォーマンスの問題

stopRequestedブール値フィールドを持つメインアプリケーションクラスがあります。受信メッセージを受信し処理する内部実行可能クラスがあります。 stopRequestedをtrueに設定する別のスレッドもあります。

このアプローチは有効で信頼できるのですか、間違っていますか?以下は

私のコードの一部ではあります:

class ApplicationClass { 

    // we set this var in another thread 
    // when it is necessary to stop 
    private stopRequested = false; 


    public ApplicationClass() { 

     // starting message processing thread 
     (new Thread(new MessageProcessing())).start(); 

    } 


    private class MessageProcessing implements Runnable { 


     public void run() { 

      while (!stopRequested) { 

       if (getNewMessagesCount() > 0) { 

        processNewMessages(); 

       } 

      } 

     } 
    }  
} 

ありがとうございました。

答えて

1

考え方はいくつかあります。 sbridgesとして

  1. (別のコアにスレッドが他の変更を参照しなくてもよい)の可視性の問題を解決するために揮発性であることがstopRequested必要性を指摘しました。
  2. getNewMessagesCount()がブロックされない場合、whileループは回転してコアを消費します。これは最小レイテンシを提供しますが、コア全体を結び付けます。
  3. あなたが列挙したコードは単純な処理キューのようです。あなたはArrayBlockingQueueで行く方が良いでしょう。
  4. コンストラクタから新しいスレッドを開始するのは危険です。心配することはApplicationClassが作成される前にgetMessageCount()processNewMessages()が呼び出された場合どうなるかです。 ApplicationClassのインスタンスは不完全な状態になる可能性があるので、かなり厄介なバグを見つけることができます。同じ理由から、コンストラクタからのイベントへのリスナーとしてコードを購読したいことは決してありません。このトピックの詳細については、Effective Javaを参照してください。
  5. whileループは、現在のスレッドが割り込みを受けてniceを置くかどうかをチェックする必要があります。それはする必要がありますwhile (!stopRequested && !Thread.currentThread().isInterrupted())

正しい並行プログラムを書くことは難しいです。私は非常に読むことをお勧めしますJava Concurrency in Practice;それはあなたに多くの苦痛を救うでしょう。

1

詳細を知らなくてもパフォーマンスにコメントするのは難しいですが、おそらくベンチマークしたいと思うでしょう。

stopRequestedをvolatileにしたい場合を除いて、コードは正しく表示されます。 volatileでない場合、処理スレッドはfalseに設定されているとは見なしません。 getNewMessageCount()などのメソッドを使用するのではなく、LinkedBlockingQueueを使用して、そのメソッドに対してpoll()メソッドを使用することができます。

+1

揮発性の使用は非常に重要です。このコードを使用してください: 'private volatile boolean stopRequested = false;' – Nayuki

+0

しかし、一般に、 'LinkedBlockingQueue.poll()'のようなものを使うと、書くコード量が減るので、バグの可能性は低くなります。 – Nayuki

関連する問題