非同期呼び出しと同期呼び出し
同期呼び出し: 順次実行。結果を再度返します。呼び出し 次の呼び出しを実行
非同期呼び出し: 呼び出しにより、返される結果を待つ必要がなく、次の呼び出しを実行します
@Async のアノテーション コードは次のとおりです:
@Target({ElementType.TYPE, ElementType.METHOD}) @Retention(RetentionPolicy.RUNTIME) @Documented public @interface Async { String value() default ""; }
アノテーションは型とメソッドで使用できます。
その値は value で定義され、デフォルトは
通常、このアノテーションは一致する必要があります @EnableAsync、元のコードは次のとおりです
@Target({ElementType.TYPE}) @Retention(RetentionPolicy.RUNTIME) @Documented @Import({AsyncConfigurationSelector.class}) public @interface EnableAsync { Class<? extends Annotation> annotation() default Annotation.class; boolean proxyTargetClass() default false; AdviceMode mode() default AdviceMode.PROXY; int order() default Integer.MAX_VALUE; }
このアノテーションは主に構成起動用のスタートアップ クラスに配置します
スタートアップ クラスに次のコードを追加します:
@SpringbootApplication @EnableAsync public class Application{ public static void main(String[] args){ SrpingApplication.run(Application.class, args); } }
次のステップは、返された関数の結果への呼び出しからのみ実行できます。は同期呼び出しと呼ばれます
サービス層コード:
public class Service{ public void test01() throws InterruptedException{ Thread.sleep(5000); System.out.println("保存日志"); } }
制御層コード モジュール:
public class Controler{ @Autowired private Service service; @GetMapping("/test") public String getTest(){ try{ System.out.println("开始"); service.test01(); System.out.println("结束"); }catch(InterruptedException e){ e.prinStackTrace(); } } }
Springboot スタートアップ クラスを介して開始した後
出力は次のようになります以下:
Start
//これは 5 秒間待機しますが、端末は待機しません。ディスプレイも閉じません。
End
非同期呼び出し、実行関数は戻り結果を待たずに次のステップを実行できます
サービス層コード:
主に @Async アノテーションを追加しますこのメソッドを特定します
public class Service{ @Async public void test01() throws InterruptedException{ Thread.sleep(500); System.out.println("保存日志"); } }
制御層コード モジュール:
サービス層関数
public class Controler{ @Autowired private Service service; @GetMapping("/test") public String getTest(){ try{ System.out.println("开始"); service.test01(); System.out.println("结束"); }catch(InterruptedException e){ e.prinStackTrace(); } } }
を呼び出してスタートアップ クラスに @EnableAsync
@SpringbootApplication @EnableAsync public class Application{ public static void main(String[] args){ SrpingApplication.run(Application.class, args); } }を開始するためのアノテーションを追加します
スレッド プールの基本的な知識については、以前の記事を参照してください:
Java でスレッドを正しく閉じる方法とスレッド プール (コードの練習を含む)ソースコード解析)
Javaスレッドプールの作成方法の詳細解析(フル)
スレッドプールを指定しない場合、デフォルトで使用されるスレッドプールはSimpleAsyncTaskExecutor(タスクが来たら作成)スレッド (常にスレッドを作成すると、過剰な CPU が発生し、OOM が発生します)。組み込みのスレッド プールには一般に欠点があります。一般に、ThreadPoolExecutor を使用することをお勧めします (スレッド プールのリソースをクリアし、リスクを回避します)
詳細は次のとおりです:
newFixedThreadPool: スレッドの数は固定されていますが、タスク キューは依然として制限されていません (最大数のスレッドはキューがいっぱいになった場合にのみ作成されます)。そのため、OOM
newCachedThreadPool: スレッドの最大数に上限はありません。多数のスレッドを作成すると、遅延が発生したり、直接 OOM
カスタム スレッド プールを使用してスレッド プールの構成を調整できます。これはより良い方法です。リソースは
@Async アノテーションを使用して AsyncConfigurer インターフェイスを見つけます (実装クラスは AsyncConfigurerSupport、デフォルトの構成とメソッドは空です)。そのため、スレッド プールを指定するようにインターフェイスを書き換えることができます。
インターフェイス AsyncConfigurer を実装することによって
AsyncConfigurerSupport を継承
TaskExecutor をカスタマイズします (ビルド済みのタスク実行デバイス)
3 番目の方法:
application.xml でスレッド プールの変数をいくつか定義します。
thread.core.size=16 thread.max.size=16 thread.queue.size=30 thread.prefix=xx-
スレッド プールを次のようにカスタマイズします。フォローします
rreee以上がJavaの@Asyncによって非同期的に呼び出されるメソッドの詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。