2012-03-24 13 views
2

ポーリングによってRabbitMQキューをリッスンしようとしています。しかし、何らかの理由でネットワークに問題が発生した場合、キューへの接続が失われると、スレッドは自動的に切断され、接続がすべて閉じられます。しかし、これはバックグラウンドタスクであり、キューが本当に大きくなり、通知を送信するまではわかりません。リスナースレッドが死んだときに、サーバーを再起動せずにサーバーへの接続が失われる方法

スレッドの正常なシャットダウンを手伝ってもらえますか(私はすでにcatch節で例外を注意深く扱っていると思います)。しかし、私は停止したスレッドを再起動する方法を知らない。

停止したスレッドの新しいインスタンスを再開できる方法はありますか。

PS:@postconstructを使用してスレッドをインスタンス化し、コンテナがすべてのBeanをロードした直後にinitスレッドを呼び出します。

答えて

2

適切な例外処理を行っていないということは私には聞こえます。あなたは "スレッドは静かに死ぬ"と言いますが、それはJavaでは起こりません。あなたの例外を監査し、次の問題を監視します:

  • 注意してください。方法については、throws Exceptionをご覧ください。これはあらゆる種類の悪を隠す。メソッドは通常、それがスローする例外を列挙する必要があります。
  • 例外が非常に多くの異なるタイプの例外をスローすると、それが大きすぎるというシグナルです。複数の小さなメソッドに分割することを検討してください。または、メソッド内の特定の例外を処理し、例外を1つスローします。
  • 可能であれば、単一の例外をキャッチする小さなtry/catchブロックを持つようにしてください。 try { ... } catch (Exception e) { ... }とコードの巨大なブロックを含めないでください。それは、再び、悪を隠す。
  • 例外が発生した場合は、盲目的に続行していないことを確認してください。これがバックグラウンドスレッドの場合は、ソケットを終了または再起動する必要があります。
  • すべての例外が適切に報告されていることを確認してください。すべてのキャッチブロックは、例外を使って何かを行う必要があります。 e.printStackTrace()が動作する可能性がありますが、問題に関する詳細情報を提供するのが通常です。

しかし、停止したスレッドを再起動する方法がわかりません。

停止したスレッドを再起動しないで、別のスレッドを開始します。スレッドがまったくシャットダウンしてはならない場合は、ソケットを再オープンするか、またはRabbitMQ接続を再開する必要があります。ここでも、適切な例外処理についてです。私はRabbitMQ知らないが、以下の擬似コードのようなものが役立つかもしれない:

public void run() { 
    while (!shutdown) { 
     Connection conn = null; 
     try { 
      conn = rabbitMq.start(); 
      processQueue(conn); 
     } catch (IOException e) { 
      // TODO: log the exception here 
     } finally { 
      // make sure we close the connection 
      if (conn != null) { conn.close(); } 
     } 
     try { 
      // we sleep here to not spin if the RabbitMQ host goes down 
      Thread.sleep(1000); 
     } catch (InterruptedException e) { 
      Thread.currentThread.interrupt(); 
      // bail if someone interrupts us 
      return; 
     } 
} 

運のベスト。

+0

ありがとうございました。グレー。私は今問題を解決することができました。私は、スレッドが例外を取得すると直ちにブロックをキャッチし、スレッドがJVMによって要求されるという印象を受けました。あなたの答えごとに明らかにそうでないケース。 –

+0

私があなたの答えから理解しているのは、たとえ例外が発生してもスレッドが生きている(例外が適切に処理されていれば)、接続を取得しようとし続けます。 .....私の理解が間違いなく正しいことを確認してください。 –

+0

はい、まさに@Anupamです。例外処理は、何かが殺されたことを意味するものではありません。 'run()'メソッドの終わりに達したときだけ、スレッドは消え去ります。決してサイレントではありません。また、メインスレッドは同じ方法であることに注意してください。 – Gray

2

例外を正しく処理している場合は、スレッドによって接続が取得されます。真のループ中に入れてキューを待ちます。ネットワーク接続(および最終的にはキュー接続)は、あなたのスレッドは接続を取得します。

+0

あなたの答えは私には正しいようです..しかし、グレイスの答えはより精巧で理解しやすいです。 –

関連する問題