1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

[Kotlin Coroutine] Semaphoreを使ってCoroutineの同時実行数を制御する

Posted at

はじめに

Kotlin Coroutineは非常に軽量であり、多数のCoroutineを簡単に起動できます。
一方で、外部APIやデータベースなどのI/O処理には必ず上限があり、無制限に並列実行するとパフォーマンス低下や障害につながることがあります。

本記事では、kotlinx.coroutinesが提供するSemaphoreを使い、Coroutineの同時実行数を制御する方法を整理します。

なぜ同時実行数を制御する必要があるのか

Coroutineはスレッドではないため、launchを大量に呼び出してもすぐに問題が顕在化しないことがあります。
しかし、以下のようなケースでは並列数の制御が重要になります。

  • 外部APIの同時接続数に制限がある
  • DBコネクション数が有限である
  • 下流サービスへの負荷を抑えたい

Coroutine向けのSemaphore

Coroutineの同時実行数を制御する方法として Semaphore を使ったものがあります。
Kotlin Coroutineでは、JavaのSemaphoreではなく
kotlinx.coroutines.sync.Semaphoreを使用します。

このSemaphoreは、スレッドをブロックせずにsuspendで待機できる点が特徴です。

import kotlinx.coroutines.sync.Semaphore
import kotlinx.coroutines.sync.withPermit

Semaphoreの基本的な使い方

Semaphoreは「同時に通過できる枠」を表します。

val semaphore = Semaphore(permits = 5)

suspend fun tame() {
  semaphore.withPermit {
    // 同時に最大5つまでしか実行されない
    feedCats()
  }
}

withPermitで囲まれた処理は、許可数を超えるとsuspendされ、
空きができたタイミングで再開されます。

Coroutineと組み合わせた例

実務でよく使うのは、複数のCoroutineを起動しつつ、
実行数だけをSemaphoreで制限するパターンです。

val semaphore = Semaphore(permits = 5)

suspend fun tame() = coroutineScope {
  repeat(100) {
    launch {
      semaphore.withPermit {
        feedCats()
      }
    }
  }
}

この例では、

  • Coroutineは100個起動される
  • 実際に処理が同時実行されるのは最大5個まで

という状態になります。

「起動数」と「同時実行数」を分離できる点が、Semaphoreの大きなメリットです。

DispatcherやChannelとの違い

Semaphoreは、処理の同時実行数そのものを制御したい場合に向いています。

  • Dispatcher
    スレッドの割り当てや実行環境を制御する
  • Channel
    キューを介したデータ受け渡しやワーカー構成に向いている
  • Semaphore
    単純に「同時に何個まで処理してよいか」を制限する

注意点

Semaphoreは万能ではありません。

  • CPUバウンドな処理にはDispatcher調整の方が適している
  • 外部I/Oや重い処理の並列数制御に向いている
  • 制限値は下流サービスの特性を考慮して決める必要がある

適切な場所で使うことで、安定した非同期処理を実現できます。

おわりに

Coroutineは軽量で扱いやすい反面、並列数を意識しないと簡単に過負荷を招きます。
Semaphoreを使えば、Coroutineの利便性を保ったまま、安全に同時実行数を制御できます。

特に外部I/Oを伴う処理では、同時実行数を適切に制御する必要があります。

1
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?