2

@Asyncアノテーションを使用して非同期呼び出しを実装しようとしています。明らかにレガシー プロジェクトであるため、Spring バージョンは 3.0.6 であるため、以降の Spring バージョンで導入された新しいインターフェイス ( AsyncConfigurer ) とリスナーはサポートされていません。

現時点では、@Async呼び出しは、電子メールの送信に必要なメソッドで問題なく機能します。呼び出しコードはメソッドを呼び出し、通常の制御を再開するために戻ります。@Async呼び出しは、別のスレッドとして呼び出されます。これはすべて非常に優れており、目的を果たしています。

@Async呼び出しは、アプリケーションで電子メールを送信するために存在するメソッドにあります。ただし、場合によっては、1000 通の電子メールがトリガーされることがあります。これにより、1000程度のスレッドが発生すると思います。これは、非常に多くのライブ スレッドがあるアプリケーションで問題を引き起こさないでしょうか? これらのスレッドは自然に終了しますか? メモリー使用量とヒープ・スペースに関して、JVM で何が起こっていますか?

さらに、そのメソッドを@Asyncとしてマークすることにより、別のメソッドからこのメソッドを呼び出そうとしましたが、スレッドが作成されていないように見え、コントロールは実際にそこで待機してそのメソッドのすべての操作を終了します。なぜそれは異なる振る舞いをするのですか?なぜそれが起こったのか分かりません。

前もって感謝します!

4

3 に答える 3

1

@Async: @Async アノテーションをメソッドに提供して、そのメソッドの呼び出しが非同期で行われるようにすることができます。つまり、呼び出し元は呼び出し時にすぐに戻り、Spring TaskExecutor に送信されたタスクでメソッドの実際の実行が行われます。

@Async のしくみ:

この非同期処理の動作は、実行時にクラスのプロキシを使用して実装されます。クラスの Bean が Spring を介して他のクラスに注入されると、Spring は実際には代わりにプロキシを注入します。したがって、プロキシの関連するメソッドが呼び出されます。

これは、非常に多くのライブ スレッドを使用するアプリケーションで問題につながることはありませんか?

はい、タスク エグゼキューターの構成を定義する際に非常に具体的にする必要があります。たとえば、タスク エグゼキュータの設定方法 (Spring xml 設定を使用する場合)。

> <bean id="taskExecutor"
> class="org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor">
>     <property name="corePoolSize" value="5" />
>     <property name="maxPoolSize" value="10" />
>     <property name="queueCapacity" value="25" /> </bean>

これらのスレッドは自然に終了しますか?

これらのスレッドは、Spring Container によって管理されます。

メモリー使用量とヒープ・スペースに関して、JVM で何が起こっていますか?

明らかに、作成されるプロキシの数が多いほど、より多くのヒープ メモリが消費されます。

なぜそれは異なる振る舞いをするのですか?

同じクラスで 2 つの非同期メソッドを作成し、別のクラスで呼び出したとします。したがって、クラス内からメソッドを呼び出す場合、Spring AOP の制限により、プロキシが機能することはありませんが、代わりに通常のメソッドとしてトリガーされます。

于 2016-10-26T15:00:59.460 に答える
1

それが生成するスレッドの数と、キューがどのようにキューに入れられるかは、taskExecutor Bean の定義方法次第です。

ドキュメントはこちら: http://docs.spring.io/spring/docs/3.1.x/spring-framework-reference/htmlsingle/spring-framework-reference.html#scheduling

于 2016-10-26T14:38:58.273 に答える