協程做用域,任何協程都必須運行在 CoroutineScope 中。html
GlobalScope
:全局做用域,非結構化併發,持有 EmptyCoroutineContext
。runBlocking
:全局做用域,通常用於 main()
或測試中,會阻塞當前線程。coroutineScope
:局部做用域,結構化併發,當全部子協程執行完畢纔會返回,而且等待過程當中不會阻塞當前線程;其中一個子協程發生異常,全部其餘子協程都會取消。supervisorScope
:局部做用域,結構化併發,當全部子協程執行完畢纔會返回,而且等待過程當中不會阻塞當前線程;其中一個子協程發生異常,不會影響其它子協程。viewModelScope
:Android ktx 提供的用於 ViewModel 中啓動協程的做用域,結構化併發,會在 ViewModel#clear()
中自動取消。CoroutineScope
:能夠本身實現該接口,實現自定義做用域。內部有個 CoroutineContext
屬性。launch
:建立一個不會阻塞當前線程的新協程,並返回給該協程一個 Job
引用。runBlocking
:建立一個新協程,該協程執行完畢前會阻塞當前線程,並返回協程執行結果。async
:建立一個不會阻塞當前線程的新協程,並返回協程執行結果類型的 Deferred
對象。withContext
:改變當前協程的 CoroutineContext,通常配合 Dispatchers
使用。協程運行的上下文,以鍵值對的方式存儲各類不一樣元素。git
EmptyCoroutineContext
:空實現,不會改變協程的行爲,相似空 Map。CoroutineName
:爲了便於調試可設置協程名稱。Job
:協程的生命週期,可用於取消協程。協程與其子協程經過 Job 聯繫在一塊兒,它會等待全部子協程都執行完畢,並在其中一個發生異常時取消全部的子協程(想要各個子協程不相互影響可使用 SupervisorJob
)。取消父協程的 Job 會取消該父協程的全部子協程 Job;其中一個子協程執行失敗或拋出 CancellationException
也會致使父協程被取消。CoroutineExceptionHandler
:處理協程內部未被捕獲的異常。ContinuationInterceptor
:協程恢復攔截器,主要在 dispatchers 中使用。協程調度器,有如下幾種實現:github
Dispatchers.Default
:每次都切換到線程池的一個不一樣線程,通常用於 CPU 密集型任務。Dispatchers.Main
:平臺相關的主線程,默認不可用,須要在各自平臺實現。Dispatchers.IO
:用於執行一些阻塞的 IO 操做,如網絡請求、數據庫讀寫,文件操做等。Dispatchers.Unconfined
:老是使用第一個可用線程,具備不肯定性,性能最優。newSingleThreadContext
:實驗性,使用一個單線程建立新的協程上下文。newFixedThreadPoolContext
:實驗性,使用一個指定大小的線程池建立新的協程上下文。通道,相似 BlockingQueue
,提供非阻塞的 send()
和 receive
,可實現生產者--消費者模型。能夠關閉通道。數據庫
fun CoroutineScope.produceSquares(): ReceiveChannel<Int> = produce {
for (x in 1..5) send(x * x)
}
val squares = produceSquares()
squares.consumeEach { println(it) } //1, 4, 9, 16, 25
複製代碼
val childNumbers = sequence {
yield(1)
print("AAA")
yieldAll(listOf(2, 3))
}
childNumbers.forEach { print(it) } //1AAA23
val nums = childNumbers.joinToString() // AAA
print(nums) // 1, 2, 3
複製代碼
共享的可變狀態與併發。安全
AtomicInteger
:可以使用原子基本類型。線程安全的。AtomicReference<V>
:可以使用原子引用類型。線程安全的。newSingleThreadContext
:使用單線程模型。Mutex
:互斥,相似 synchronized
或 ReentranLock
。給關鍵代碼塊加鎖,確保不會被同時執行。private val mutex = Mutex()
mutex.withLock { /**/ } 複製代碼
actor
協程構建器是一個雙重的 produce
協程構建器。一個 actor 與它接收消息的通道相關聯,而一個 producer 與它發送元素的通道相關聯。 在高負載下比鎖更有效,由於在這種狀況下它老是有工做要作,並且根本不須要切換到不一樣的上下文。網絡
// 計數器 Actor 的各類類型
sealed class CounterMsg
object IncCounter : CounterMsg() // 遞增計數器的單向消息
object PrintCounter : CounterMsg() // 打印的單向消息
class GetCounter(val response: CompletableDeferred<Int>) : CounterMsg() // 攜帶回復的請求
// 這個函數啓動一個新的計數器 actor
fun CoroutineScope.counterActor() = actor<CounterMsg> {
var counter = 0 // actor 狀態
for (msg in channel) { // 即將到來消息的迭代器
when (msg) {
is IncCounter -> counter++
is PrintCounter -> print(counter)
is GetCounter -> msg.response.complete(counter)
}
}
}
複製代碼
我是 xiaobailong24,您能夠經過如下平臺找到我:併發