協(xié)程概念
協(xié)程首先不是一個(gè)線程或者進(jìn)程,是一個(gè)新的概念,不可以用線程或者進(jìn)程混淆,可以理解為具有掛起功能的函數(shù)調(diào)用(因?yàn)閿y程可以在自己控制切換上下文)
kotlin中協(xié)程大多指的是在kotlinx.coroutines擴(kuò)展包中的攜程庫(kù)
協(xié)程的啟動(dòng)方式
協(xié)程的啟動(dòng)方式
1·GlobalScope.launch
GlobalScope:A global CoroutineScope not bound to any job.
沒(méi)有綁定任何協(xié)程作用域的協(xié)程
launch:Launches a new coroutine without blocking the current thread
啟動(dòng)一個(gè)不阻塞線程的協(xié)程
使用方式如下:
GlobalScope.launch {
//執(zhí)行代碼塊
}
2·runBlocking
Runs a new coroutine and blocks the current thread interruptibly until its completion
啟動(dòng)一個(gè)直到執(zhí)行完畢都會(huì)阻塞當(dāng)前線程的協(xié)程
使用代碼如下
fun doCoroutine()=runBlocking {
//執(zhí)行代碼塊
}
fun doCoroutine(){
runBlocking {
//執(zhí)行代碼塊
}
}
3·CoroutineScope.launch
Launches a new coroutine without blocking the current thread
啟動(dòng)一個(gè)不阻塞線程的協(xié)程
但是由于該方法是CoroutineScope的擴(kuò)展函數(shù),所以一般在協(xié)程作用域中可以直接調(diào)用launch啟動(dòng),一般用于子攜程或者當(dāng)前作用域協(xié)程,可以理解GlobalScope.launch 是該方法的特殊擴(kuò)展方法,相當(dāng)于子類的launch方法
fun doCoroutine()=runBlocking {
launch{
}
}
public fun CoroutineScope.launch(_,_,_): Job {
...
return coroutine
}
public object GlobalScope : CoroutineScope {
/**
* Returns [EmptyCoroutineContext].
*/
override val coroutineContext: CoroutineContext
get() = EmptyCoroutineContext
}
4·coroutineScope{} 和 CoroutineScope()
先看runBlocking的入?yún)⒑蚻aunch的入?yún)ⅲㄊ÷园妫?/p>
public fun <T> runBlocking(_, block: suspend CoroutineScope.() -> T): T {
val coroutine = BlockingCoroutine<T>(newContext, currentThread, eventLoop)
coroutine.start(CoroutineStart.DEFAULT, coroutine, block)
return coroutine.joinBlocking()
}
public fun CoroutineScope.launch(_, _, block: suspend CoroutineScope.() ->Unit): Job {
coroutine.start(start, coroutine, block)
return coroutine
}
block在兩個(gè)函數(shù)入?yún)⒅卸际且粋€(gè)CoroutineScope的擴(kuò)展方法,所以coroutineScope{}是在協(xié)程作用域中當(dāng)構(gòu)建器用的
代碼執(zhí)行方法
fun doCoroutine()=runBlocking {
coroutineScope{
}
}
CoroutineScope(EmptyCoroutineContext).launch { }
還有幾種以后再說(shuō)
關(guān)鍵字 suspend
suspend關(guān)鍵字使用來(lái)標(biāo)識(shí)協(xié)程方法的前綴
所有因?yàn)樵趌aunch和runBlocking的入?yún)lock中都被suspend修飾了,所以可以理解為一個(gè)在協(xié)程作用域中執(zhí)行的方法都需要被suspend修飾。
fun doCoroutine() = runBlocking {
launch (block = block)
coroutineScope(block = block)
}
var block: suspend CoroutineScope.() -> Unit =
{
}
Job 任務(wù)管理
通過(guò)GlobalScope.launch 或者runblocking創(chuàng)建的協(xié)程都會(huì)返回一個(gè)Job類型,Job是給協(xié)程使用者提供管理協(xié)程的封裝體,包括啟動(dòng),取消等等操作這里就不一一記錄
Dispatchers 協(xié)程調(diào)度器
Dispatchers.Default
默認(rèn)調(diào)度 它由JVM上的共享線程池支持。默認(rèn)情況下,此調(diào)度程序使用的最大并行級(jí)別等于CPU內(nèi)核數(shù),至少為兩個(gè)( 機(jī)翻)
Dispatchers.Main
主線程
Dispatchers.IO
任務(wù)線程 和Default 公用一個(gè)線程池
newSingleThreadContext
獨(dú)立線程,最好能管理生命周期
Unconfined
用于嵌套調(diào)度,類似想做個(gè)遞歸(求大神指點(diǎn))
啟動(dòng)模式
launch的start參數(shù) 有四種類型
DEFAULT
默認(rèn),不傳或傳入此參數(shù)會(huì)立即執(zhí)行協(xié)程
LAZY
launch后不立即執(zhí)行,需要獲取其job發(fā)起執(zhí)行
ATOMIC
執(zhí)行前不可取消的
UNDISPATCHED
在當(dāng)前線程立即執(zhí)行
使用方法
runBlocking {
launch ( CoroutineStart.DEFAULT)
}
以上都是協(xié)程的基本概念