协程做用域,任何协程都必须运行在 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,您能够经过如下平台找到我:并发