runBlocking 是一个协程构建器,它是一个函数,返回值是一个 Coroutine 对象

1
2
3
4
5
6
7
8
9
这个kotlin预制的一个函数,返回值是一个Coroutine对象,同时会阻塞该协程运行的线程。
/**
*params: context:CoroutineContext ,协程上下文对象
*
*params: block:suspend CoroutineScope.() -> T 一个lambda函数
*/
public fun <T> runBlocking(context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> T): T{
...
}

启动一个协程,协程只能在协程作用域中运行,协程作用域是 CoroutineScope,协程无法脱离其存在,下面是 launch 的源码,

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17


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 是协程启动器启动选项,有 4 个枚举类型:

  • DEFAULT 根据协程上下文环境立即执行协程体
  • LAZY 只在协程需要执行的时候才执行
  • ATOMIC 类似 DEFAULT,只是不可以取消
  • UNDISPATCHED 立即执行协程体直到遇到当前线程第一个挂起点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
//class: StandaloneCoroutine -> AbstractCoroutine
//start: CoroutineStart.DEFAULT
//receiver: StandaloneCoroutine
//block: 协程体
public fun <R> start(start: CoroutineStart, receiver: R, block: suspend R.() -> T) {
initParentJob()
start(block, receiver, this)
}


internal fun initParentJob() {
initParentJobInternal(parentContext[Job])
}

internal fun initParentJobInternal(parent: Job?) {
assert { parentHandle == null }
if (parent == null) {
parentHandle = NonDisposableHandle
return
}
parent.start() // make sure the parent is started
@Suppress("DEPRECATION")
val handle = parent.attachChild(this)
parentHandle = handle
// now check our state _after_ registering (see tryFinalizeSimpleState order of actions)
if (isCompleted) {
handle.dispose()
parentHandle = NonDisposableHandle // release it just in case, to aid GC
}
}


//CoroutineStart 启动协程体
public operator fun <R, T> invoke(block: suspend R.() -> T, receiver: R, completion: Continuation<T>): Unit =
when (this) {
DEFAULT -> block.startCoroutineCancellable(receiver, completion)
ATOMIC -> block.startCoroutine(receiver, completion)
UNDISPATCHED -> block.startCoroutineUndispatched(receiver, completion)
LAZY -> Unit // will start lazily
}



internal fun <R, T> (suspend (R) -> T).startCoroutineCancellable(
receiver: R, completion: Continuation<T>,
onCancellation: ((cause: Throwable) -> Unit)? = null
) =
runSafely(completion) {
//创建协程
createCoroutineUnintercepted(receiver, completion)
.intercepted()
.resumeCancellableWith(Result.success(Unit), onCancellation)
}



//因为kotlin编译器会将协程体表达式编译成一个SuspendLambda对象。
SuspendLambda -> ContinuationImpl -> BaseContinuationImpl -> Continuation
public actual fun <R, T> (suspend R.() -> T).createCoroutineUnintercepted(
receiver: R,
completion: Continuation<T>
): Continuation<Unit> {
val probeCompletion = probeCoroutineCreated(completion)
return if (this is BaseContinuationImpl)
create(receiver, probeCompletion)
else {
createCoroutineFromSuspendFunction(probeCompletion) {
(this as Function2<R, Continuation<T>, Any?>).invoke(receiver, it)
}
}
}