検索
ホームページJava&#&チュートリアルSpringBoot でマルチスレッドをエレガントに使用する方法

クイック使用

非同期呼び出しを有効にするには、@EnableAsync アノテーションを SpringBoot アプリケーションに追加する必要があります。通常、スレッド プールが構成され、非同期メソッドは特定のスレッド プールによって完了されます。

@Configuration
@EnableAsync
public class AsyncConfiguration {
 
    @Bean("doSomethingExecutor")
    public Executor doSomethingExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        // 核心线程数:线程池创建时候初始化的线程数
        executor.setCorePoolSize(10);
        // 最大线程数:线程池最大的线程数,只有在缓冲队列满了之后才会申请超过核心线程数的线程
        executor.setMaxPoolSize(20);
        // 缓冲队列:用来缓冲执行任务的队列
        executor.setQueueCapacity(500);
        // 允许线程的空闲时间60秒:当超过了核心线程之外的线程在空闲时间到达之后会被销毁
        executor.setKeepAliveSeconds(60);
        // 线程池名的前缀:设置好了之后可以方便我们定位处理任务所在的线程池
        executor.setThreadNamePrefix("do-something-");
        // 缓冲队列满了之后的拒绝策略:由调用线程处理(一般是主线程)
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.DiscardPolicy());
        executor.initialize();
        return executor;
    }
 
}

使用方法は非常に簡単で、非同期が必要なメソッドに @Async アノテーションを追加します。

@RestController
public class AsyncController {
 
    @Autowired
    private AsyncService asyncService;
 
    @GetMapping("/open/something")
    public String something() {
        int count = 10;
        for (int i = 0; i < count; i++) {
            asyncService.doSomething("index = " + i);
        }
        return "success";
    }
}
 
 
@Slf4j
@Service
public class AsyncService {
 
    // 指定使用beanname为doSomethingExecutor的线程池
    @Async("doSomethingExecutor")
    public String doSomething(String message) {
        log.info("do something, message={}", message);
        try {
            Thread.sleep(1000);
        } catch (InterruptedException e) {
            log.error("do something error: ", e);
        }
        return message;
    }
}

Access: 127.0.0.1:8080/open/something、ログは次のとおりです。

2023 -02-06 23:42:42.486 INFO 21168 --- [io-8200-exec-17] x.g.b.system.controller.AsyncController : 何かを終了します、時間 8 ミリ秒
2023-02-06 23:42:42.488 INFO 21168 --- [ do-something-1] x.gits.boot.system.service.AsyncService : 何かをしてください、message=index = 0
2023-02 -06 23:42:42.488 情報 21168 --- [ do-something-5] x.gits.boot.system.service.AsyncService : 何かをしてください、message=index = 4
2023-02-06 23:42 :42.488 情報 21168 --- [ do-something- 4] x.gits.boot.system.service.AsyncService : 何かをしてください、message=index = 3
2023-02-06 23:42:42.488 INFO 21168 - -- [ do-something-6] x.gits .boot.system.service.AsyncService : 何かを実行します、message=index = 5
2023-02-06 23:42:42.488 INFO 21168 --- [ do- something-9] x.gits.boot.system.service.AsyncService : 何かをします、message=index = 8
2023-02-06 23:42:42.488 INFO 21168 --- [ do-something-8] x .gits.boot.system.service.AsyncService : 何かをしてください、message=index = 7
2023-02-06 23:42:42.488 INFO 21168 --- [do-something-10] x.gits.boot。 system.service.AsyncService : 何かをします、message=index = 9
2023-02-06 23:42:42.488 INFO 21168 --- [ do-something-7] x.gits.boot.system.service.AsyncService : 何かをしてください、message=index = 6
2023-02-06 23:42:42.488 INFO 21168 --- [ do-something-2] x.gits.boot.system.service.AsyncService : 何かをしてください、メッセージ=index = 1
2023-02-06 23:42:42.488 INFO 21168 --- [ do-something-3] x.gits.boot.system.service.AsyncService : 何かをしてください、message=index = 2

非同期実行の効果が得られ、設定したスレッドプールが使用されていることがわかります。

非同期メソッドの戻り値を取得する

非同期メソッドに戻り値がある場合、非同期メソッドの実行結果の戻り値を取得するにはどうすればよいでしょうか?このとき、非同期で呼び出す必要があるメソッドの戻り値は CompletableFuture です。

CompletableFuture は、Feature の拡張機能です。Feature は単純な非同期タスクのみを処理できますが、CompletableFuture は複数の非同期タスクの複雑な組み合わせを実行できます。次のように:

@RestController
public class AsyncController {
 
    @Autowired
    private AsyncService asyncService;
 
    @SneakyThrows
    @ApiOperation("异步 有返回值")
    @GetMapping("/open/somethings")
    public String somethings() {
        CompletableFuture<String> createOrder = asyncService.doSomething1("create order");
        CompletableFuture<String> reduceAccount = asyncService.doSomething2("reduce account");
        CompletableFuture<String> saveLog = asyncService.doSomething3("save log");
 
        // 等待所有任务都执行完
        CompletableFuture.allOf(createOrder, reduceAccount, saveLog).join();
        // 获取每个任务的返回结果
        String result = createOrder.get() + reduceAccount.get() + saveLog.get();
        return result;
    }
}
 
 
@Slf4j
@Service
public class AsyncService {
 
    @Async("doSomethingExecutor")
    public CompletableFuture<String> doSomething1(String message) throws InterruptedException {
        log.info("do something1: {}", message);
        Thread.sleep(1000);
        return CompletableFuture.completedFuture("do something1: " + message);
    }
 
    @Async("doSomethingExecutor")
    public CompletableFuture<String> doSomething2(String message) throws InterruptedException {
        log.info("do something2: {}", message);
        Thread.sleep(1000);
        return CompletableFuture.completedFuture("; do something2: " + message);
    }
 
    @Async("doSomethingExecutor")
    public CompletableFuture<String> doSomething3(String message) throws InterruptedException {
        log.info("do something3: {}", message);
        Thread.sleep(1000);
        return CompletableFuture.completedFuture("; do something3: " + message);
    }
}

アクセス インターフェイス

C:\Users\Administrator>curl -X GET "http://localhost:8080/open/something" -H "accept: * /*"
何かをする 1: 注文を作成;
何かをする 2: アカウントを減らす;
何かをする 3: ログを保存

コンソール上の主なログは次のとおりです:

2023-02-06 00:27:42.238 情報 5672 --- [ do-something-3] x.gits.boot.system.service.AsyncService : do something3: ログを保存
2023-02- 06 00:27:42.238 INFO 5672 --- [ do-something-2] x.gits.boot.system.service.AsyncService : do something2: アカウントを減らす
2023-02-06 00:27 :42.238 INFO 5672 --- [ do-something-1] x.gits.boot.system.service.AsyncService : do something1: create order

Notes

@Async アノテーションいくつかのシナリオは失敗しました。これは、@Async アノテーションが明らかに使用されましたが、マルチスレッドが使用されていなかったことを意味します。

  • 非同期メソッドは static キーワードで変更されます;

  • 非同期クラスは Spring コンテナの Bean ではありません (通常はアノテーション @ を使用します)コンポーネントと @Service であり、Spring によってスキャンできます);

  • @EnableAsync アノテーションは SpringBoot アプリケーションに追加されません;

  • In同じクラス、メソッド呼び出し @Async アノテーションを持つ別のメソッドの場合、アノテーションは有効になりません。その理由は、@Async アノテーションが付けられたメソッドがプロキシ クラスで実行されるためです。

アノテーション @Async を使用した非同期メソッドの戻り値は、void または Future とそのサブクラスのみであることに注意してください。戻り結果が他の型の場合、メソッドは引き続き非同期で実行されますが、戻り値はすべて null です。ソース コードの一部は次のとおりです:

AsyncExecutionInterceptor#invoke

SpringBoot でマルチスレッドをエレガントに使用する方法

上記の例を通して、@Async は実際には Future または CompletableFuture を渡します。非同期実行の場合、Spring はそれをカプセル化し、使いやすくしています。

以上がSpringBoot でマルチスレッドをエレガントに使用する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明
この記事は亿速云で複製されています。侵害がある場合は、admin@php.cn までご連絡ください。
Javaがクロスプラットフォームデスクトップアプリケーションを開発するための人気のある選択肢なのはなぜですか?Javaがクロスプラットフォームデスクトップアプリケーションを開発するための人気のある選択肢なのはなぜですか?Apr 25, 2025 am 12:23 AM

javaispopularforsoss-platformdesktopapplicationsduetoits "writeonce、runaynay" philosophy.1)itusesbytecodatiTatrunnanyjvm-adipplatform.2)ライブラリリケンディンガンドジャヴァフククレアティック - ルルクリス

Javaでプラットフォーム固有のコードを作成する必要がある場合がある状況について話し合います。Javaでプラットフォーム固有のコードを作成する必要がある場合がある状況について話し合います。Apr 25, 2025 am 12:22 AM

Javaでプラットフォーム固有のコードを作成する理由には、特定のオペレーティングシステム機能へのアクセス、特定のハードウェアとの対話、パフォーマンスの最適化が含まれます。 1)JNAまたはJNIを使​​用して、Windowsレジストリにアクセスします。 2)JNIを介してLinux固有のハードウェアドライバーと対話します。 3)金属を使用して、JNIを介してMacOSのゲームパフォーマンスを最適化します。それにもかかわらず、プラットフォーム固有のコードを書くことは、コードの移植性に影響を与え、複雑さを高め、パフォーマンスのオーバーヘッドとセキュリティのリスクをもたらす可能性があります。

プラットフォームの独立性に関連するJava開発の将来の傾向は何ですか?プラットフォームの独立性に関連するJava開発の将来の傾向は何ですか?Apr 25, 2025 am 12:12 AM

Javaは、クラウドネイティブアプリケーション、マルチプラットフォームの展開、および言語間の相互運用性を通じて、プラットフォームの独立性をさらに強化します。 1)クラウドネイティブアプリケーションは、GraalvmとQuarkusを使用してスタートアップ速度を向上させます。 2)Javaは、埋め込みデバイス、モバイルデバイス、量子コンピューターに拡張されます。 3)Graalvmを通じて、JavaはPythonやJavaScriptなどの言語とシームレスに統合して、言語間の相互運用性を高めます。

Javaの強力なタイピングは、プラットフォームの独立性にどのように貢献しますか?Javaの強力なタイピングは、プラットフォームの独立性にどのように貢献しますか?Apr 25, 2025 am 12:11 AM

Javaの強力なタイプ化されたシステムは、タイプの安全性、統一タイプの変換、多型を通じてプラットフォームの独立性を保証します。 1)タイプの安全性は、コンパイル時間でタイプチェックを実行して、ランタイムエラーを回避します。 2)統一された型変換ルールは、すべてのプラットフォームで一貫しています。 3)多型とインターフェイスメカニズムにより、コードはさまざまなプラットフォームで一貫して動作します。

Javaネイティブインターフェイス(JNI)がプラットフォームの独立性をどのように妥協できるかを説明します。Javaネイティブインターフェイス(JNI)がプラットフォームの独立性をどのように妥協できるかを説明します。Apr 25, 2025 am 12:07 AM

JNIはJavaのプラットフォームの独立を破壊します。 1)JNIは特定のプラットフォームにローカルライブラリを必要とします。2)ローカルコードをターゲットプラットフォームにコンパイルおよびリンクする必要があります。3)異なるバージョンのオペレーティングシステムまたはJVMは、異なるローカルライブラリバージョンを必要とする場合があります。

Javaのプラットフォームの独立性を脅かしたり強化したりする新しいテクノロジーはありますか?Javaのプラットフォームの独立性を脅かしたり強化したりする新しいテクノロジーはありますか?Apr 24, 2025 am 12:11 AM

新しいテクノロジーは、両方の脅威をもたらし、Javaのプラットフォームの独立性を高めます。 1)Dockerなどのクラウドコンピューティングとコンテナ化テクノロジーは、Javaのプラットフォームの独立性を強化しますが、さまざまなクラウド環境に適応するために最適化する必要があります。 2)WebAssemblyは、Graalvmを介してJavaコードをコンパイルし、プラットフォームの独立性を拡張しますが、パフォーマンスのために他の言語と競合する必要があります。

JVMのさまざまな実装は何ですか、そしてそれらはすべて同じレベルのプラットフォームの独立性を提供しますか?JVMのさまざまな実装は何ですか、そしてそれらはすべて同じレベルのプラットフォームの独立性を提供しますか?Apr 24, 2025 am 12:10 AM

JVMの実装が異なると、プラットフォームの独立性が得られますが、パフォーマンスはわずかに異なります。 1。OracleHotspotとOpenJDKJVMは、プラットフォームの独立性で同様に機能しますが、OpenJDKは追加の構成が必要になる場合があります。 2。IBMJ9JVMは、特定のオペレーティングシステムで最適化を実行します。 3. Graalvmは複数の言語をサポートし、追加の構成が必要です。 4。AzulzingJVMには、特定のプラットフォーム調整が必要です。

プラットフォームの独立性は、開発コストと時間をどのように削減しますか?プラットフォームの独立性は、開発コストと時間をどのように削減しますか?Apr 24, 2025 am 12:08 AM

プラットフォームの独立性により、開発コストが削減され、複数のオペレーティングシステムで同じコードセットを実行することで開発時間を短縮します。具体的には、次のように表示されます。1。開発時間を短縮すると、1セットのコードのみが必要です。 2。メンテナンスコストを削減し、テストプロセスを統合します。 3.展開プロセスを簡素化するための迅速な反復とチームコラボレーション。

See all articles

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

Video Face Swap

Video Face Swap

完全無料の AI 顔交換ツールを使用して、あらゆるビデオの顔を簡単に交換できます。

ホットツール

SecLists

SecLists

SecLists は、セキュリティ テスターの究極の相棒です。これは、セキュリティ評価中に頻繁に使用されるさまざまな種類のリストを 1 か所にまとめたものです。 SecLists は、セキュリティ テスターが必要とする可能性のあるすべてのリストを便利に提供することで、セキュリティ テストをより効率的かつ生産的にするのに役立ちます。リストの種類には、ユーザー名、パスワード、URL、ファジング ペイロード、機密データ パターン、Web シェルなどが含まれます。テスターはこのリポジトリを新しいテスト マシンにプルするだけで、必要なあらゆる種類のリストにアクセスできるようになります。

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SAP NetWeaver Server Adapter for Eclipse

SAP NetWeaver Server Adapter for Eclipse

Eclipse を SAP NetWeaver アプリケーション サーバーと統合します。

SublimeText3 Linux 新バージョン

SublimeText3 Linux 新バージョン

SublimeText3 Linux 最新バージョン

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)