KotlinのJobとキャンセル処理の基本!初心者でもわかる安全な停止方法
生徒
「Kotlinの非同期処理で、処理を途中で止めたいときってどうすればいいんですか?」
先生
「それにはJobという仕組みを使って、キャンセル処理を行うことができます。安全に止める方法もちゃんと用意されているんですよ。」
生徒
「ただ止めるだけじゃなくて、安全にっていうのが気になります!」
先生
「それでは、KotlinのJobとキャンセル処理の基本をしっかり学んでいきましょう!」
1. KotlinのJobとは?
Kotlinで非同期処理(コルーチン)を使うときに、自動的に作られるのがJobです。Jobは、そのコルーチンが「今動いているのか」「止められたのか」などの状態を管理しています。
たとえば、お料理ロボットをイメージしてください。Jobはそのロボットの「お仕事メモ」のようなものです。「今は炒め中」とか「今は停止中」とか、状態を記録しています。
2. キャンセルとは?なぜ必要?
長く時間がかかる処理や、ユーザーの操作で途中でやめたくなるような処理において、キャンセル(中止)はとても重要です。たとえば、ネットから大きなデータをダウンロード中に「やっぱりやめた」となったら、すぐに止めたいですよね。
そのようなときに使うのが、Jobのcancel()メソッドです。
3. Jobを使ったキャンセル処理の基本
次は、基本的なJobの使い方とキャンセル方法のサンプルコードを見てみましょう。
import kotlinx.coroutines.*
fun main() = runBlocking {
val job = launch {
repeat(5) { i ->
println("処理中:$i")
delay(500)
}
}
delay(1000)
println("キャンセル実行!")
job.cancel()
job.join()
println("メイン終了")
}
4. 実行結果の例
処理中:0
処理中:1
キャンセル実行!
メイン終了
このように、途中でキャンセルすると処理が止まってメイン処理に戻ります。
5. キャンセル時の注意点
実はcancel()を呼んでも、delay()やyield()のような「中断可能なポイント」がなければ、コルーチンは止まりません。
だから、キャンセル可能にしたい処理の中には、中断ポイントをちゃんと入れておく必要があります。delayやcheckCancellationなどがそれに該当します。
6. isActiveを使ってキャンセルを安全にチェック
処理の中でキャンセルされているかどうかを自分で確認したいときは、isActiveプロパティを使います。
import kotlinx.coroutines.*
fun main() = runBlocking {
val job = launch {
var i = 0
while (isActive) {
println("ループ中:$i")
delay(300)
i++
}
}
delay(1000)
println("キャンセル開始")
job.cancel()
job.join()
println("終了")
}
isActiveはコルーチンがまだ動いているかどうかを示す変数で、「キャンセルされたらfalse」になります。
7. finallyで後処理を安全に行う
キャンセルされたあとに「掃除」や「ログの記録」などをしたい場合は、try-finallyを使うと便利です。finallyの中は、キャンセルされても必ず実行されます。
import kotlinx.coroutines.*
fun main() = runBlocking {
val job = launch {
try {
repeat(5) { i ->
println("実行中:$i")
delay(500)
}
} finally {
println("後処理実行!")
}
}
delay(1000)
println("キャンセルします")
job.cancelAndJoin()
println("メイン終了")
}
8. job.cancelAndJoin()とは?
cancelAndJoin()は、cancel()とjoin()をセットで行う便利な関数です。「キャンセルして終わるまで待つ」を1行で書けます。非同期処理を安全に止めたいときによく使われます。
9. よくあるミスと対策
初心者がやりがちなミスと、それを防ぐポイントを紹介します。
- cancelだけで終わったと思う:
joinやcancelAndJoinでちゃんと待ちましょう。 - isActiveを確認しない:ループなどでは
isActiveでキャンセル状態を確認するのが安全です。 - 後処理を書かない:
finallyを使って確実に後片付けしましょう。