網站首頁 編程語言 正文
啟動協程的基本方式
1.GlobalScope.launch
代碼示例:
fun testGlobalScope() {
GlobalScope.launch {
println("Coroutinue started!")
delay(1000L)
println("Hello World!")
}
println("After launch!")
Thread.sleep(2000L)
println("Process end!")
}
/**
* After launch!
* Coroutinue started!
* Hello World!
* Process end!
*/
@DelicateCoroutinesApi
public object GlobalScope : CoroutineScope {
/**
* Returns [EmptyCoroutineContext].
*/
override val coroutineContext: CoroutineContext
get() = EmptyCoroutineContext
}
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
}
launch函數是CoroutineScope的擴展函數,它有三個參數:
- context: CoroutineContext = EmptyCoroutineContext, 第一個參數是協程上下文,它的默認值是 EmptyCoroutineContext,如果不傳這個參數,默認就會使用 EmptyCoroutineContext。也可以傳入 Kotlin 官方為我們提供的 Dispatchers,來指定協程運行的線程池。(Dispatchers.IO、Dispatchers.Unconfined、Dispatchers.Main)
- start: CoroutineStart = CoroutineStart.DEFAULT,第二個參數是協程的啟動模式,默認值是CoroutineStart.DEFAULT,CoroutineStart 是一個枚舉類,一共有:DEFAULT、LAZY、ATOMIC、UNDISPATCHED。
- block: suspend CoroutineScope.() -> Unit,第三個參數是函數類型block,它的類型是suspend CoroutineScope.() -> Unit。本質是一個掛起函數。
- 函數的返回值是一個 Job,它其實代表的是協程的句柄,并不能返回協程的執行結果。
2.runBlocking 啟動協程
代碼示例
fun testRunBlocking2() {
runBlocking {
println("Coroutinue started!")
delay(1000L)
println("Hello World!")
}
println("After Launch")
Thread.sleep(2000L)
println("Process end")
}
/**
* Coroutinue started!
* Hello World!
* After Launch
* Process end
*/
@Throws(InterruptedException::class)
public actual fun <T> runBlocking(context: CoroutineContext, block: suspend CoroutineScope.() -> T): T {
contract {
callsInPlace(block, InvocationKind.EXACTLY_ONCE)
}
val currentThread = Thread.currentThread()
val contextInterceptor = context[ContinuationInterceptor]
val eventLoop: EventLoop?
val newContext: CoroutineContext
if (contextInterceptor == null) {
// create or use private event loop if no dispatcher is specified
eventLoop = ThreadLocalEventLoop.eventLoop
newContext = GlobalScope.newCoroutineContext(context + eventLoop)
} else {
// See if context's interceptor is an event loop that we shall use (to support TestContext)
// or take an existing thread-local event loop if present to avoid blocking it (but don't create one)
eventLoop = (contextInterceptor as? EventLoop)?.takeIf { it.shouldBeProcessedFromContext() }
?: ThreadLocalEventLoop.currentOrNull()
newContext = GlobalScope.newCoroutineContext(context)
}
val coroutine = BlockingCoroutine<T>(newContext, currentThread, eventLoop)
coroutine.start(CoroutineStart.DEFAULT, coroutine, block)
return coroutine.joinBlocking()
}
runBlocking是普通函數,第一個參數:context: CoroutineContext,協程上下文。第二個參數是函數類型,block: suspend CoroutineScope.() -> T,函數類型是有返回值類型 T 的,與 runBlocking 的返回值類型是一樣的,runBlocking 其實是可以從協程當中返回執行結果的。
fun testRunBlocking() {
val runBlockingResult = runBlocking {
delay(500L)
return@runBlocking "HaHa"
}
println("result:$runBlockingResult")
}
result:HaHa
runBlocking特點:
runBlocking 啟動的協程會阻塞當前線程的執行。
3.async啟動協程
使用 async{} 創建協程,可以通過它返回的Deferred拿到協程的執行結果。
代碼示例
fun testAsync() {
runBlocking {
val deferred = async {
println("do async:${Thread.currentThread().name}")
delay(1000L)
return@async "do completed"
}
println("After async:${Thread.currentThread().name}")
val result = deferred.await()
println("Result is: $result")
}
}
After async:main @coroutine#1
do async:main @coroutine#2
Result is: do completed
public fun <T> CoroutineScope.async(
context: CoroutineContext = EmptyCoroutineContext,
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.start(start, coroutine, block)
return coroutine
}
async注意點
- async 啟動協程以后,不會阻塞當前程序的執行流程。
- async{}的返回值,是一個 Deferred 對象,它的 await() 方法,就可以拿到協程的執行結果。
- await只是等待執行完,并不是觸發執行。
原文鏈接:https://blog.csdn.net/zhangying1994/article/details/126689643
相關推薦
- 2022-05-06 SQL查看表字段信息如:字段名、字段類型、字段精度、字段大小、索引、主鍵等
- 2022-07-22 SQL?Server使用CROSS?APPLY與OUTER?APPLY實現連接查詢_MsSql
- 2022-11-16 Django?報錯:Broken?pipe?from?('127.0.0.1',?58924)的解決
- 2022-11-23 Android移除Message的方法分享_Android
- 2022-11-30 React中常見的TypeScript定義實戰教程_React
- 2023-02-10 C++?stack與queue使用方法詳細講解_C 語言
- 2022-12-10 深入分析React源碼中的合成事件_React
- 2023-02-06 C語言實現文件讀寫功能流程_C 語言
- 最近更新
-
- window11 系統安裝 yarn
- 超詳細win安裝深度學習環境2025年最新版(
- Linux 中運行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎操作-- 運算符,流程控制 Flo
- 1. Int 和Integer 的區別,Jav
- spring @retryable不生效的一種
- Spring Security之認證信息的處理
- Spring Security之認證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權
- redisson分布式鎖中waittime的設
- maven:解決release錯誤:Artif
- restTemplate使用總結
- Spring Security之安全異常處理
- MybatisPlus優雅實現加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務發現-Nac
- Spring Security之基于HttpR
- Redis 底層數據結構-簡單動態字符串(SD
- arthas操作spring被代理目標對象命令
- Spring中的單例模式應用詳解
- 聊聊消息隊列,發送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠程分支