ホームページ  >  記事  >  Java  >  Java 非同期タスクの実装と分析

Java 非同期タスクの実装と分析

PHPz
PHPz転載
2023-04-22 20:49:061473ブラウズ

1. 非同期タスクとは

生活でもプログラムでも、大きく分けて同期と非同期の2種類に分けられます。

同期: たとえば、ハイディラオを食べに行く場合、最初に鍋の底を注文し、次に皿を注文し、次にウェイターが鍋の底を持ってきて、次に皿を持ってきて、最後にあなたが注文する必要があります。このプロセスは順番に実行する必要があります。

非同期タスク: ハイディラオを食べに行きましょう。たくさんの人が食事をしています。あなたの前にたくさんの人がいます。レストランに入る前に、列に並んで待つ必要があるかもしれません。でも、途中でトイレに行きたくなったら、戻ってきたらまた並ばなければなりません。電話システムがあり、まず列に並んで番号を取得すると、マッサージを受けたり、映画を見たり、スパに行ったり、ミルクティーを買ったりすることができます...いよいよあなたの番です。この時点で、列に並んでいることが通知で表示され、入場できます。このプロセスは非同期です。

2. SpringBoot Async

最初は、スレッド プールを開いて、スレッド プールにタスクを投げて完了することを考えていました。

後になって、SpringBoot にはもっと便利な非同期フレームワーク Async があることを思い出しました。

コードも非常にシンプルで、非同期実行が必要なメソッドに @Async を追加し、 @EnableAsync を追加するだけです。 SpringBoot スタートアップ クラスへの移行. 以上です

    @Async
    public void task() {
        // do something
    }

3. 落とし穴日記

コードは小さいですが、コード量が減っても落とし穴は減りません。

便宜上、ローカルでデモを構築し、コードを直接アップロードしました

@RestController
public class AsyncController {
    @Autowired
    private AsyncService asyncService;

    @GetMapping("/v1/say")
    public String sayV1() {
        asyncService.sayV1();
        return "success1";
    }

    @GetMapping("/v2/say")
    public String sayV2() {
        asyncService.sayV2();
        return "success2";
    }
}
@Service
public class AsyncService {
    public void sayV1() {
        try {
            Thread.sleep(3000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("hello world");
    }

    @Async
    public void sayV2() {
        try {
            Thread.sleep(3000L);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        System.out.println("hello world");
    }
}

これは、2 つのインターフェイス /v1/say と /v2/say を提供する非常に単純なデモです。 1 つは同期実行用、もう 1 つは 3 秒間スリープすることで時間のかかるタスクをシミュレートする非同期実行です。

通常通り問題なく起動します。同期実行の場合は、メインスレッドが戻るまで 3 秒待ちます。非同期実行するとすぐに戻って3秒待つ Helloworld

が出力されるのですが、ブレークポイントを追加したところ問題が発生しました。

最初に hello world を出力する行にブレークポイントを追加しました。効果は、出力前にブロックされる点を除いて元のブレークポイントと同じですが、メイン スレッドの復帰には影響しません。

Java 非同期タスクの実装と分析

編集

しかし、メソッドが入ってくる場所にブレークポイントを追加すると、メインスレッドが実際にブロックされていることがわかりました。

Java 非同期タスクの実装と分析

編集

4. 解決方法

さまざまな問題解決、@Async が有効にならず、非同期タスクはメイン スレッドが完了するまで待機します。戻っても何も起こりません。効果的な解決策を見つけてください。

後で同僚が、デバッグ機能によってスレッドがブロックされている可能性があることを思い出させてくれました。

試してみようという姿勢で、デバッグ構成を見つけました。

Java 非同期タスクの実装と分析

Edit

ブレークポイントは、JVM をブロックすることを選択できます。または、現在のスレッドをブロックします。デフォルトでは、jvm がブロックされます。

スレッドへの一時停止を選択すると、メインスレッドはブロックされなくなります

以上がJava 非同期タスクの実装と分析の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はyisu.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。