kotlin之coroutine学习笔记

runBlocking

声明

1
2
3
4
5
6
7
8
9
10
@Throws(InterruptedException::class)
public fun <T> runBlocking(context: CoroutineContext = EmptyCoroutineContext, block: suspend CoroutineScope.() -> T): T {
val currentThread = Thread.currentThread()
val eventLoop = if (context[ContinuationInterceptor] == null) BlockingEventLoop(currentThread) else null
val newContext = newCoroutineContext(context + (eventLoop ?: EmptyCoroutineContext))
val coroutine = BlockingCoroutine<T>(newContext, currentThread, privateEventLoop = eventLoop != null)
coroutine.initParentJob(context[Job])
block.startCoroutine(coroutine, coroutine)
return coroutine.joinBlocking()
}

功能

创建一个coroutine并且阻塞当前线程直到区块执行完毕,这个一般是用于桥接一般的阻塞式编程方式到coroutine编程方式的,不应该在已经是coroutine的地方使用。

run

声明

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
public suspend fun <T> run(
context: CoroutineContext,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend () -> T
): T = suspendCoroutineOrReturn sc@ { cont ->
val oldContext = cont.context
// fast path #1 if there is no change in the actual context:
if (context === oldContext || context is CoroutineContext.Element && oldContext[context.key] === context)
return@sc block.startCoroutineUninterceptedOrReturn(cont)
// compute new context
val newContext = oldContext + context
// fast path #2 if the result is actually the same
if (newContext === oldContext)
return@sc block.startCoroutineUninterceptedOrReturn(cont)
// fast path #3 if the new dispatcher is the same as the old one.
// `equals` is used by design (see equals implementation is wrapper context like ExecutorCoroutineDispatcher)
if (newContext[ContinuationInterceptor] == oldContext[ContinuationInterceptor]) {
val newContinuation = RunContinuationDirect(newContext, cont)
return@sc block.startCoroutineUninterceptedOrReturn(newContinuation)
}
// slowest path otherwise -- use new interceptor, sync to its result via a full-blown instance of RunCompletion
require(!start.isLazy) { "$start start is not supported" }
val completion = RunCompletion(
context = newContext,
delegate = cont,
resumeMode = if (start == CoroutineStart.ATOMIC) MODE_ATOMIC_DEFAULT else MODE_CANCELLABLE)
completion.initParentJob(newContext[Job]) // attach to job
start(block, completion)
completion.getResult()
}

功能

在指定的CoroutineContext中调用指定的suspend区块。 该方法会导致当前CoroutineContext中的coroutine挂起并等待该代码块执行完毕。

launch

声明

1
2
3
4
5
6
7
8
9
10
11
12
13
public fun launch(
context: CoroutineContext = DefaultDispatcher,
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.initParentJob(context[Job])
start(block, coroutine, coroutine)
return coroutine
}

功能

创建运行在CoroutineContext中的coroutine,返回的Job支持取消、启动等操作,不会挂起父coroutine上下文;可以在非coroutine中调用。

参数context可以显示指定。默认为DefaultDispatcher
参数start表示coroutine的启动选项。默认为CoroutineStart.DEFAULT
参数block表示coroutine里面执行的代码。

默认请情况下,coroutine是会被立即调度执行的。如果参数start的值为CoroutineStart.LAZY,那么会返回一个新建状态的coroutine。 可以通过显示调用Job.start()方法来启动该coroutine

如果在该coroutine里面有未捕获的异常,那么会导致该coroutine的父coroutine取消。

async

声明

1
2
3
4
5
6
7
8
9
10
11
12
13
public fun <T> async(
context: CoroutineContext = DefaultDispatcher,
start: CoroutineStart = CoroutineStart.DEFAULT,
block: suspend CoroutineScope.() -> T
): Deferred<T> {
val newContext = newCoroutineContext(context)
val coroutine = if (start.isLazy)
LazyDeferredCoroutine(newContext, block) else
DeferredCoroutine<T>(newContext, active = true)
coroutine.initParentJob(context[Job])
start(block, coroutine, coroutine)
return coroutine
}

功能

创建运行在CoroutineContext中的coroutine,并且带回返回值(返回的是Deferred,我们可以通过await等方式获得返回值)

参考

Kotlin Coroutines(协程)

文章目录
  1. 1. runBlocking
    1. 1.1. 声明
    2. 1.2. 功能
  2. 2. run
    1. 2.1. 声明
    2. 2.2. 功能
  3. 3. launch
    1. 3.1. 声明
    2. 3.2. 功能
  4. 4. async
    1. 4.1. 声明
    2. 4.2. 功能
  5. 5. 参考
|