0
0

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】Kotlinで理解する「並行処理(Concurrency)」徹底解説

Last updated at Posted at 2025-10-15

はじめに

― マルチタスクのように見せる「同時進行の仕組み」 ―


1. 並行処理とは?

並行処理(Concurrency) とは、
複数の処理を「同時に進行しているように見せる」仕組みです。

実際には CPU は 1つのタスクを高速に切り替えながら動かしており、
人間の目には同時進行のように見えます。

例えるなら

一人のシェフが、
「スープを温めながら」「サラダを切り」「肉を焼く」
― 少しずつ同時進行しているように見える状態。


2. 並行処理と並列処理の違い

比較項目 並行処理(Concurrency) 並列処理(Parallelism)
CPU構成 1コアでも可能 複数コアが必要
実行の仕組み タスクを高速に切り替える 複数のタスクを同時実行
主な用途 ネット通信、ファイル操作など I/O 待機 数値計算、暗号化などCPU負荷処理
Kotlin Dispatcher Dispatchers.IO Dispatchers.Default
体感 同時に動いているように見える 実際に同時に動く

3. Kotlin における並行処理の考え方

Kotlin では Coroutine(コルーチン) を使って、
スレッドを直接操作せずに「軽量な並行処理」を実現できます。

特徴

  • 数千単位のコルーチンを1スレッドで実行可能
  • I/O待ち(ネット通信・DB操作)中に他の処理を進められる
  • CPUリソースを無駄にしない

4. シンプルな並行処理の例

import kotlinx.coroutines.*

fun main() = runBlocking {
    launch {
        delay(1000)
        println("🍜 ラーメンが完成!")
    }
    launch {
        delay(500)
        println("🥗 サラダが完成!")
    }
    println("👨‍🍳 調理開始!")
}

実行結果

👨‍🍳 調理開始!
🥗 サラダが完成!
🍜 ラーメンが完成!

launch により2つの処理が「並行」に進行します。
ただし、これは「並列」ではなく、スレッド切り替えによる同時進行です。


5. I/O処理に強い理由

並行処理は「待ち時間のある処理」に特に有効です。
例えば、複数のAPIを同時に叩く場合:

import kotlinx.coroutines.*

suspend fun fetchUser() : String {
    delay(1000)
    return "User Data"
}

suspend fun fetchOrders() : String {
    delay(1000)
    return "Order List"
}

fun main() = runBlocking {
    val start = System.currentTimeMillis()

    val user = async(Dispatchers.IO) { fetchUser() }
    val orders = async(Dispatchers.IO) { fetchOrders() }

    println("${user.await()} & ${orders.await()}")

    println("処理時間: ${System.currentTimeMillis() - start}ms")
}

実行結果

User Data & Order List
処理時間: 約1000ms

それぞれのAPIが並行に進むため、
本来2秒かかる処理が 約1秒 で完了します。


6. KotlinのDispatcherで見る並行性

Dispatcher 主な用途 並行 or 並列
Dispatchers.IO I/O待機処理(通信、DB、ファイル) 並行処理
Dispatchers.Default CPU計算系タスク 並列処理
Dispatchers.Main Android UI操作 シングルスレッド
newSingleThreadContext("MyThread") 明示的に単一スレッド シリアル処理

Dispatchers.IO は、内部的には数十スレッドを切り替えながら
I/O待機を効率的に管理します。


7. 並行処理で注意すべき点

問題 説明 対策
競合状態(Race Condition) 複数タスクが同じデータに同時アクセス MutexAtomic クラスを使用
キャンセル漏れ スコープ外のタスクが中断されない CoroutineScope を正しく設計
リソース枯渇 無制限にタスクを並行実行 Semaphore で同時実行数を制限
エラーハンドリング 親子関係で例外が伝播 SupervisorScope を利用

8. 構造化並行性(Structured Concurrency)

Kotlinのコルーチンでは、
「構造化並行性(Structured Concurrency)」 という設計原則が導入されています。

意味:

コルーチンのライフサイクルを「スコープ(Scope)」で管理し、
親タスクが終了すれば子タスクも確実に終了する仕組み。

suspend fun loadData() = coroutineScope {
    val user = async { fetchUser() }
    val orders = async { fetchOrders() }
    println("${user.await()} + ${orders.await()}")
}

これにより、キャンセルや例外が発生しても安全に並行処理を終了できます。


9. 並行処理の実用例

  • 複数のAPIを同時に呼び出し、結果をまとめる
  • ファイルの一括ダウンロード
  • データベース・キャッシュ・ネットワークを同時問い合わせ
  • Androidで「画像読み込み+ネット更新+アニメーション」を同時に行う

10. 図解で理解する並行処理の流れ

実際のスレッドは1つでも、
OSが切り替えながら「同時進行のように」見せています。


まとめ

要点 内容
並行処理とは タスクを交互に進めて「同時に動いているように見せる」
並列処理との違い 並列=物理的同時、並行=論理的同時
Kotlinでの手段 コルーチン + Dispatchers.IO
利点 I/O待機を効率化し、応答性を高める
注意点 スコープ管理とリソース制御が重要

0
0
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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?