【Kotlin】Coroutineを理解する

#はじめに
Kotlin 1.1からCoroutineが実験的に組み込まれました。
Coroutineとは**「特定のスレッドに束縛されない、中断可能な計算インスタンス」**です。
非同期処理で用いられますが、`Thread`よりも軽量で、実行途中で処理を`中断・再開`することができます。

#準備
Coroutineを利用するために、`build.gradle`に下記の情報を追記します。
今回は2018/09/30時点での最新版(`0.30.0`)を使用しています。
更新状況は[ここ](https://github.com/Kotlin/kotlinx.coroutines/releases)から確認できます。

```gradle:build.gradle
dependencies {
    ...
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:0.30.0"
}
```
```gradle:build.gradle
kotlin {
    experimental {
        coroutines 'enable'
    }
}
```
```gradle:build.gradle
repositories {
    jcenter()
}
```
#使い方
Coroutineの作成には`Coroutineビルダー`を使用します。
##runBlocking
現在のスレッドをブロックするビルダーです。任意の型を返します。

```kotlin
runBlocking {
    // 何かしらの処理
}
```
###Sample
```kotlin
fun main(args:Array<String>) {
    println(1)
    runBlocking {
        println(2)
    }
    println(3)
}

/**
 * 実行結果
 * 1
 * 2
 * 3
 */
```
##launch

戻り値として`Job`を返すビルダーです。

`0.26.1`から`launch`が`GlobalScope.launch`になりました。

```kotlin
GlobalScope.launch {
    // 何かしらの処理 
}
```
###Sample
現在のスレッドをブロックしないため、`launch`内の処理が実行される前にプログラムが終了します。

```kotlin
fun main(args:Array<String>) {
    println(1)
    launch {
        println(2)
    }
    println(3)
}

/**
 * 実行結果
 * 1
 * 3
 */
```

引数で実行するスレッドを指定できます。
引数なしの場合は**Dispatchers.Default**が設定されます。

`0.26.1`から`CommonPool`が`Dispatchers.Default`になりました。
`0.26.1`から`UI`が`Dispatchers.Unconfined`になりました。

```kotlin
/**
 * Dispatchers.Default -> バックグラウンドスレッド
 * Dispatchers.Unconfined -> メインスレッド
 */
GlobalScope.launch(Dispatchers.Unconfined) {
    // 何かしらの処理 
}
```
`Job#join()`を利用すれば、呼び出し先のcoroutineの終了まで呼び出し元のcoroutineを中断できます。

```kotlin
runBlocking {
    GlobalScope.launch() {
        // 何かしらの処理 
    }.join()
}
```
###Sample

```kotlin
fun main(args:Array<String>) = runBlocking {
    println(1)
    GlobalScope.launch {
        println(2)
    }.join()
    println(3)
}

/**
 * 実行結果
 * 1
 * 2
 * 3
 */
```
##async
戻り値として`Deferred<T>`を返すビルダーです。
Coroutineの処理が終わったタイミングで戻り値を取得できます。

`0.26.1`から`async`が`GlobalScope.async`になりました。

```kotlin
GlobalScope.async {
    // 何かしらの処理 
}
```
###Sample
`launch`同様、現在のスレッドをブロックしないため、`async`内の処理が実行されません。

```kotlin
fun main(args:Array<String>) {
    println(1)
    GlobalScope.async {
        println(2)
    }
    println(3)
}

/**
 * 実行結果
 * 1
 * 3
 */
```
`Job#join()`同様、`Deferred<T>#await()`を利用すれば、呼び出し先のCoroutineの終了まで呼び出し元のCoroutineを中断できます。

```kotlin
runBlocking {
    GlobalScope.async {
        // 何かしらの処理 
    }.await()
}
```
###Sample
```kotlin
fun main(args:Array<String>) = runBlocking {
    println(1)
    GlobalScope.async {
        println(2)
    }.await()
    println(3)
}

/**
 * 実行結果
 * 1
 * 2
 * 3
 */
```
#Suspend関数
Coroutineを中断できる関数です。`suspend`をつけることで宣言できます。
CoroutineかSuspend関数内からのみ実行できます。

```kotlin
suspend fun sampleSuspending(){
     // 何かしらの処理       
}
```
###Sample
`delay`はSuspend関数なので実行できます。

```kotlin
fun main(args:Array<String>) = runBlocking {
    println(1)
    sampleSuspending()
    println(3)
}

suspend fun sampleSuspending() {
    delay(1000)
    println(2) 
}

/**
 * 実行結果
 * 1
 * (1秒中断)
 * 2
 * 3
 */ 
```
#まとめ
非同期処理を直感的に理解しやすく、とても簡潔に記述できるようになりました。

#参考
[Coroutines - Kotlin Programming Language]
(https://kotlinlang.org/docs/reference/coroutines.html)
[AndroidでKotlin Coroutinesを使ってみる]
(http://tech.furyu.jp/blog/?p=6388)
[eaglesakuraの技術ブログ]
(https://eaglesakura.hatenablog.com/entry/2018/09/21/142152)
[Kotlin の Coroutine を概観する]
(https://qiita.com/kawmra/items/ee4acb7db61f70dec9a8)
[入門Kotlin coroutines]
(https://qiita.com/k-kagurazaka@github/items/8595ca60a5c8d31bbe37)