3

発信キューが必要なメッセージ処理アプリケーション (電子メール) を作成しています。私がこれを設計した方法は、Executor Service と BlockingQueue に支えられたシングルトン キュー クラス ThreadedQueueSender を持つことです。さらに、javax.mail.Transport オブジェクトのスレッド プールを使用して、発信 SMTP サーバーへの接続を取得および解放します。

add(MimeMessage)このクラスは、ワーク キュー ( ) にメッセージを追加するメソッド を公開しますBlockingQueue

クラスのインスタンス化時に、ExecutorServiceは固定数のスレッド (5 としましょう) に初期化されThreadPoolExecutorます。各スレッドのメソッドは、割り込みを検出したとき (が呼び出されたとき)run()にのみ終了する無限ループにあります。ExecutorService.shutdownNow()

この run メソッドはBlockingQueue.poll()、使用可能なメッセージがなくなるまでブロックせずにワーク キューからメッセージを取得するために使用します。次にTransport、接続プールからオブジェクトを要求し、接続を開き、取得したすべてのメッセージを送信し、接続を閉じて、Transportオブジェクトを返します。

これは機能しますが、アプリケーションの存続期間中に実行されるスレッドの数が固定されているため、ExecutorService を十分に活用していないと感じています。また、同時実行フレームワークに処理させるのではなく、自分でワーク キューを管理しています。他の人はこの機能をどのように実装しますか? 各受信メッセージを Runnable でラップしてから、送信ロジックを実行する方がよいでしょうか?

ありがとうございます。コメントをお待ちしております。

ライアン

4

2 に答える 2

1

エグゼキューター サービスによって実行されるすべての作業に対して、タスクを作成する必要があります。

たとえば、MimeMessage を保持し、メール送信をラップする呼び出し可能な「MailSendingTask」を作成できます。これらの MailSendingTasks をエグゼキューターに送信してキューに入れます。Executor は、作成されるスレッドの数を決定します (スレッド プールの下限と上限を設定して構成します)。

2 つまたは 3 つのクラス/インターフェイスを作成するだけで済みます

  • シンプルな send(MimeMessage msg) メソッドを提供する 1 つの MailService インターフェイス
  • MailService を実装し、構成されたエグゼキュータへの参照を保持する 1 つの MailServiceImplementation クラス
  • MimeMessage オブジェクトへの参照を保持し、メール送信を行う呼び出し可能なインターフェイスを実装する 1 つのクラス MailSenderTask。

MailSenderTask で使用できるメール ソケット接続を管理する追加のサービスを作成することで、さらに進めることもできます。

「キャンセル」を追加したい場合は、Future および FutureTask クラスを確認する必要があります。

于 2009-09-28T18:35:34.333 に答える
0

メッセージを でRunnableまとめると、作業キューを無制限にするか、キューがいっぱいになったときに何が起こるかを処理する必要があります。 ThreadPoolExecutorこの状況に対処するためのいくつかのポリシーを示します。詳細については、 ThreadPoolExecutor javadocを参照してください。- あきらめて、自分で実行する / 何かを捨てる

他にできることは、スレッドプールがそのコアサイズを超えてスレッドを作成できるようにすることです。スレッドがどのように生成され、いつ取得されるかは、ThreadPoolExecutorコンストラクターへの最初の 4 つの引数によって記述されます。これが実際にどれだけうまく機能するかは、リソースのボトルネックによって異なります。

BlockingQueue.pollまた、ではなく、あなたの状況での利点は何BlockingQueue.takeですか? どちらも割り込み可能で、スレッドにはタスクが 1 つしかないため、ブロッキングは望ましくありません。

于 2009-09-28T18:34:53.237 に答える