3

メールの送信に使用するメソッドがあります。このメソッドをロックして、一度に 1 つのスレッドだけがアクセスできるようにし、残りのスレッドが同時にプールされるようにします。メソッドを同期するか、Spring @transactional PROPAGATION_REQUIRED を使用する必要がありますか?

私のサービス層で

 //each time use new thread to send out email
  public  void sendThroughSMTP(List<String> emails,String subject,String content){

            //each time will open and sent through port 25.  dont u think this will caused too many threads spawned?
            BlastEmailThread blastEmailThread = new BlastEmailThread(emails,subject,content);

            blastEmailThread.start();


}
4

6 に答える 6

7

インスタンスレベルのものを使用しないことで、メソッドをスレッドセーフにしないのはなぜですか?

ただし、Spring のトランザクション管理がここにどのように適合するかはわかりません。つまり、Spring はトランザクション マネージャーをほとんど提供していません。つまりDataSourceTransactionManager、これJtaTransactionManagerHibernateTransactionManagerすべてデータベースの永続性に関するものです。この電子メール送信のために何を設定しますか?

そもそもスレッドセーフを心配する理由を最初に示す必要があると思います。ほとんどの場合、関連するコード スニペットか何かを見せてください。そうすれば、何か提案できるかもしれません。

【追記】

そのメソッドへの呼び出しごとにスレッドを生成し、状態から何も使用しない場合、メソッドを作成する理由synchronized. メソッドを同期化しても、スレッド数が制限されることはありません。同期のために、新しいスレッドを開始する前に、前のスレッドが作業を終了している可能性があります。スレッドを生成するプロセスが遅くなる可能性があります。

ただし、非常に多くのスレッドが実行されており、メモリが不足していることがわかるまで、これを使用する必要があります。そして、本当に時間の前にそれに取り組みたい場合は、Semaphoreのようなブロックメカニズムを選択する必要があります。

于 2009-12-23T03:58:48.620 に答える
3

もう 1 つの可能性は、JMS キューを使用して、メール送信コードをメッセージ駆動型 Bean に (または Spring JMS を介して) 配置することです。その後、アプリ サーバーを使用して、MDB の同時インスタンスの数を制御し、送信メールをそのように調整できます。

于 2009-12-23T08:16:33.560 に答える
3

それがあなたの質問に答えるかどうかはわかりませんが、すべてのメールに対して新しいスレッドを作成して start を呼び出す代わりに、ExecutorまたはExecutorServiceをクラスのメンバーとして持つことができます。実装として、ThreadPoolExecutorをプール サイズは 1 です。sendMail メソッドは Runnables をエグゼキュータに送信します。

于 2009-12-23T07:41:26.503 に答える
2

Sping 3.0 では @Async アノテーションを使用してタスクを実行できるため、メソッドは後で実行され、メールの送信を待たずにメソッドが直接返されます。

@Async
public  void sendThroughSMTP(List<String> emails,String subject,String content){
//Send emails here, you can directly send lots of email
}

次に、アプリケーション コンテキストで指定し、タスク スキーマの xmlns を追加することを忘れないでください。

一定時間実行を遅らせたい場合は、メソッドに @Scheduled アノテーションを使用できます。

@Async および @Scheduled に関する詳細なチュートリアルは、次の場所にあります。

http://blog.springsource.com/2010/01/05/task-scheduling-simplifications-in-spring-3-0/

于 2010-10-20T13:28:41.123 に答える
1

サービスを aにして、メソッドsingletonに追加synchronizedします。

于 2014-07-16T21:48:45.787 に答える
1

Spring @Transactional は、あなたのケースでは正しく使用されていません。最善の策は、同期化されたメソッドを使用し、メソッドが何百回も呼び出された場合にスレッド プーリングを追加することです。しかし、ここではスレッドプールは必要ないと思います。

スレッドを使用してブラスト メールを送信する場合、メソッドを同期する意味は何ですか? あるプロセスがメソッドを呼び出してメールを送信すると、最初のメール送信プロセスがまだ完了していなくても、他のプロセスがメソッドを呼び出します。

メール送信プロセスを調整する場合は、キュー (コレクション) を検討し、同期ブロックでコレクションを保護する必要があります。そのキューを監視する別のプロセスを作成し、キューにアイテムが1つある場合はポップしてブラストメールを送信し、電子メールの送信プロセスが完了するまで待ってキューを再度確認し、アイテムがある場合は電子メールの送信プロセスを続行します。キューにアイテムがない場合は、監視スレッドを一定時間スリープさせ、スリープ時間が終了したらキューを再度チェックします。

于 2009-12-23T07:55:52.583 に答える