Kotlin之協程初探

協程是一種線程框架,它運行在線程上,每一個協程就是一個耗時任務,協程內部程序是按順序執行,它是一種非阻塞式的,用戶能夠手動控制協程的掛起和運行;android

官方介紹: 協程經過將複雜性放入庫來簡化異步編程。程序的邏輯能夠在協程中順序地表達,而底層庫會爲咱們解決其異步性。該庫能夠將用戶代碼的相關部分包裝爲回調、訂閱相關事件、在不一樣線程(甚至不一樣機器)上調度執行,而代碼則保持如同順序執行同樣簡單;編程

引入bash

kotlin{
    experimental {
        coroutines 'enable'
    }
}
// 協程
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-core:1.2.1'
implementation 'org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1'
複製代碼

建立協程

GlobalScope.launch {
    for(i in 1..3){
    println("協程任務1打印: $i")
    }
    delay(200)
    for(i in 1..3){
    println("協程任務2打印: $i")
    }
}
for(i in 1..3){
    println("主線程打印: $i")
}
複製代碼

能夠經過日誌看到協程是按照順序執行:閉包

2020-05-26 15:30:58.673 24381-24381/? I/System.out: 主線程打印: 1
2020-05-26 15:30:58.673 24381-24381/? I/System.out: 主線程打印: 2
2020-05-26 15:30:58.673 24381-24381/? I/System.out: 主線程打印: 3
2020-05-26 15:30:58.674 24381-24446/? I/System.out: 協程任務1打印: 1
2020-05-26 15:30:58.674 24381-24446/? I/System.out: 協程任務1打印: 2
2020-05-26 15:30:58.674 24381-24446/? I/System.out: 協程任務1打印: 3
2020-05-26 15:30:58.878 24381-24448/? I/System.out: 協程任務2打印: 1
2020-05-26 15:30:58.878 24381-24448/? I/System.out: 協程任務2打印: 2
2020-05-26 15:30:58.878 24381-24448/? I/System.out: 協程任務2打印: 3
複製代碼

源碼框架

public fun CoroutineScope.launch(
    context: CoroutineContext = EmptyCoroutineContext,
    start: CoroutineStart = CoroutineStart.DEFAULT,
    block: suspend CoroutineScope.() -> Unit
): Job {
    val newContext = newCoroutineContext(context)
    val coroutine = if (start.isLazy)
    LazyStandaloneCoroutine(newContext, block) else
    StandaloneCoroutine(newContext, active = true)
    coroutine.start(start, coroutine, block)
    return coroutine
}
複製代碼

CoroutineStart: 啓動模式,默認就是DEFAULT,即建立協程就啓動,還有一個LAZY,懶加載模式,須要調用start纔會啓動;異步

  • DEFAULT:默認模式,當即啓動協程;
  • ATOMIC:
  • UNDISPATCHED:
  • LAZY:懶加載模式,須要的時候,再啓動;

block: 閉包方法體,定義協程內須要執行的操做;async

Job: 建立協程的返回值,能夠把job當作協程對象自己;異步編程

  • start():啓動協程;
  • join():等待協程執行完畢;
  • cancel():取消一個協程包含內部的子協程,可是async修飾的協程若是已開始則無法取消;

Suspend: 用來修飾協程的方法,被修飾的方法能夠被協程掛起,suspend修飾的方法只能被suspend修飾的方法調用;函數

GlobalScope.async: async和launch的區別就是async有返回值ui

GlobalScope.launch(Dispatchers.IO){
    // 多協程間 suspend函數運行
    val suspend2 = GlobalScope.async(Dispatchers.IO){
        return@async suspend2()
    }
    println("hello ${suspend2.isActive}")
    println("hello ${suspend2.isActive} ${suspend2.await()}")
    println("hello ${suspend2.isActive}")
//  println("hello $suspend1 $suspend2 thread:${Thread.currentThread().name}")
}
複製代碼

打印結果

2020-05-26 19:23:42.426 9411-9485/? I/System.out: hello true
2020-05-26 19:23:42.427 9411-9487/? I/System.out: hello suspend2 start, thread:DefaultDispatcher-worker-3
2020-05-26 19:23:42.441 9411-9485/? I/System.out: hello suspend2 end, thread:DefaultDispatcher-worker-1
2020-05-26 19:23:42.442 9411-9485/? I/System.out: hello true suspend2
2020-05-26 19:23:42.442 9411-9485/? I/System.out: hello false
複製代碼
相關文章
相關標籤/搜索