@Asyncとは?使い方や引数を徹底解説!【具体例付き】

@Asyncとは

「非同期でメソッドを実行するためのアノテーション」 のことです。

通常、Javaのメソッドは呼び出し元が処理完了を待って次の行へ進みますが、@Async を使うことでメソッドを別のスレッドで実行し、呼び出し元は待たずに次の処理に進めるようになります。

例えば、メール送信やファイルのアップロード処理など、ユーザーの待ち時間を減らしたいケースで効果を発揮します。


基本的な使い方

それでは、実際に @Async を使った例を見てみましょう。以下のコードを見てください。

@Service
public class NotificationService {

    @Async
    public void sendEmail(String email) {
        // 実際にはメールを送信する処理
        System.out.println("Sending email to " + email);
        try {
            Thread.sleep(3000); // メール送信に3秒かかると仮定
        } catch (InterruptedException e) {
            Thread.currentThread().interrupt();
        }
        System.out.println("Email sent to " + email);
    }
}

説明

  1. @Async アノテーションを sendEmail() メソッドに付与することで、このメソッドは非同期に実行されます。
  2. 実行するたびに新しいスレッドが作られるため、呼び出し元は待たずに次の処理へ進むことができます。

呼び出し例

@Autowired
private NotificationService notificationService;

notificationService.sendEmail("example@example.com");
System.out.println("次の処理を実行中...");

この場合、「次の処理を実行中…」がすぐに表示され、その後に「Sending email to example@example.com」が続きます。つまり、メール送信が非同期で処理されます。


@Asyncの設定方法

1. @EnableAsync を追加する

@Async を使用するためには、Spring Bootアプリケーションの設定クラス(通常は @SpringBootApplication が付与されているクラス)に @EnableAsync アノテーションを付ける必要があります。

@SpringBootApplication
@EnableAsync
public class MyApplication {
    public static void main(String[] args) {
        SpringApplication.run(MyApplication.class, args);
    }
}

2. 非同期メソッドの戻り値

非同期メソッドには、戻り値として void 以外に CompletableFutureFuture を指定することができます。これにより、非同期処理の結果を受け取ることが可能です。

@Async
public CompletableFuture<String> fetchData() {
    try {
        Thread.sleep(2000);
    } catch (InterruptedException e) {
        Thread.currentThread().interrupt();
    }
    return CompletableFuture.completedFuture("データ取得完了");
}

呼び出し例

CompletableFuture<String> future = notificationService.fetchData();
future.thenAccept(result -> System.out.println(result));

@Asyncの応用編

1. 非同期メソッドに引数を渡す

@Async メソッドは引数を持つことができ、通常のメソッドと同様に値を渡すことが可能です。

@Async
public void processTask(int taskId) {
    System.out.println("Processing task: " + taskId);
}

2. 複数の非同期メソッドの同時実行

複数の @Async メソッドを同時に呼び出すことで、並列処理を実現できます。

notificationService.sendEmail("user1@example.com");
notificationService.sendEmail("user2@example.com");
notificationService.sendEmail("user3@example.com");

各メール送信処理が別々のスレッドで実行されるため、全体の処理が高速化されます。

3. 例外処理

非同期メソッド内で例外が発生しても、デフォルトでは呼び出し元に通知されません。必要に応じて、 AsyncUncaughtExceptionHandler を実装して例外をキャッチすることができます。

@Component
public class AsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
    @Override
    public void handleUncaughtException(Throwable ex, Method method, Object... params) {
        System.out.println("Exception in method: " + method.getName() + ", Message: " + ex.getMessage());
    }
}

@EnableAsync
@Configuration
public class AppConfig implements AsyncConfigurer {
    @Override
    public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
        return new AsyncExceptionHandler();
    }
}

@Asyncの引数

1. value属性でExecutorを指定

@Async アノテーションには value 属性を使って、使用する Executor を指定することができます。

@Async("customExecutor")
public void performAsyncTask() {
    // カスタムExecutorで非同期処理
}

customExecutor は、以下のように設定します。

@Bean(name = "customExecutor")
public Executor taskExecutor() {
    ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
    executor.setCorePoolSize(5);
    executor.setMaxPoolSize(10);
    executor.setQueueCapacity(25);
    executor.initialize();
    return executor;
}

2. Timeoutの設定

非同期処理にタイムアウトを設定したい場合、 @Transactional(timeout) を併用して管理することができます。


おわりに

使いどころ

@Async は、以下のようなシナリオで役立ちます:

  • 非同期なAPIリクエストの処理: ユーザーが待つ必要のない処理(例: ログの保存、メール通知など)を非同期化。
  • バッチ処理: 複数のデータを並行して処理。
  • レスポンスタイムの向上: ユーザーにすぐ応答を返したいが、裏で時間のかかる処理を行いたいとき。

まとめ

今回は、Springの @Async について詳しく見てきました。非同期処理を簡単に導入できる便利なツールで、アプリケーションのパフォーマンス向上に大いに役立ちます。ぜひ、この機会に @Async を活用して、効率的なWebアプリケーション開発を進めてください!

もっと詳しく知りたい方は、Spring公式ドキュメントを見てみてくださいね。

他の記事が見たい方はこちら!↓↓↓

@GroupSequenceの使い方と引数を徹底解説!【初心者向け】

@AssertTrueと@AssertFalseの使い方と違いを徹底解説!【初心者向け】

@Max, @Min, @Sizeアノテーションの使い方と違いを解説!【初心者向け】

@NotNull、@NotBlank、@NotEmptyの違いは?【初心者向け】

@DateTimeFormatと@NumberFormatの使い方徹底解説!

タイトルとURLをコピーしました