kotlin-協程(什么是一個協程)

1.什么指一個協程對于線程來說一個thread就是就是指一個線程,thread為什么成為線程呢?因為他實現了對線程的一個抽象管理,可以管理這個線程,啟動,可以查看各種信息

那么協程呢?

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) elseStandaloneCoroutine(newContext, active = true)coroutine.start(start, coroutine, block)return coroutine
}可以看到,啟動協程的時候創建了一個StandaloneCoroutine的對象,這個對象是Job的實現類,返回了一個job對象。

job有什么方法呢?

job.start()  //啟動協程, start: CoroutineStart = CoroutineStart.LAZY
// ,的時候得使用job.start方法才會啟動協程,才會調用block的代碼
job.cancel() //取效協程
job.isActive  //判讀協程的狀態
job.join()   //當前的協程阻塞,等待job的協程結束后,再執行當前協程的代碼
job.children //子協程的job對象
job.parent //父協程的job對象
job.cancelChildren() //取消所有子協程

那是不是意味著可以把job對象看作一個協程對象呢? 可以也行,但不是全部,job只是管理了協程流程相關的功能,比如開啟結束等,但是像協程的名字等是沒有的

CoroutineScope是信息最多的,包含可以獲取協程的調度器,job等,以及調用launch 和 async去啟動一個新的協程,而StandaloneCoroutine也是繼承CoroutineScope的

而CoroutineScope里面有一個屬性是CoroutineScope,里面全是協程的配置信息

比如:調度器,協程名稱,啟動模式等

public interface CoroutineScope {public val coroutineContext: CoroutineContext
}

協程的父子協程

val parentJob = launch {childJob =  launch {delay(200)}}

協程的父子協程是根據job來決定的,在上面的代碼中,會把parentJob賦值給childJob的parent屬性,會把childJob賦值給parentJob的childJob屬性。那怎么相互拿到對方的job呢?

在父協程中啟動launch的時候,因為本身就是通過 。CoroutineScope啟動的,而CoroutineScope的 coroutineContext 中就可以拿到這個Job。

  runBlocking {var childJob:Job?= nullval parentJob = launch(Dispatchers.IO) {childJob =  launch {delay(200)}}println("parentJOb${parentJob }")println("childJob=${childJob }")println("childJOb = parentJOb=${childJob?.parent == parentJob }")}

其實看源碼可以看到他是復制了父類的coroutineContext的內容

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) elseStandaloneCoroutine(newContext, active = true)coroutine.start(start, coroutine, block)return coroutine
}
我們看newCoroutineContextnewCoroutineContext是CoroutineScope的擴展函數,
所以可以拿到當前調用他的launch的CoroutineScope的coroutineContext,和傳入的context共同創建一個新的contextpublic actual fun CoroutineScope.newCoroutineContext(context: CoroutineContext): CoroutineContext {val combined = foldCopies(coroutineContext, context, true)val debug = if (DEBUG) combined + CoroutineId(COROUTINE_ID.incrementAndGet()) else combinedreturn if (combined !== Dispatchers.Default && combined[ContinuationInterceptor] == null)debug + Dispatchers.Default else debug
}

?

kotlin?

這里說下我的疑惑點:

第一:parentJob是在??println之前賦值的嗎??

打印結果:

parentJObStandaloneCoroutine{Active}@4b553d26
childJob=StandaloneCoroutine{Active}@69a3d1d
childJOb = parentJOb=true

val parentJob = launch(Dispatchers.IO) {childJob =  launch {delay(200)}}

這個代碼,雖然指定了Dispatchers.IO,但是只是說把block函數扔進了子線程,但是賦值給parentJob是在主線程的,所以在println之前,但是childJob不一定了

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) elseStandaloneCoroutine(newContext, active = true)coroutine.start(start, coroutine, block)return coroutine    //立即返回對象
}

kotlin的父子協程關系就是通過job來綁定的。

假如,我們把childJob的launch傳一個job進去,他們就不是父子協程了,這個時候childJob的父協程是傳進去的job,注意傳進去的job是父job.

fun main() {runBlocking {CoroutineScope(EmptyCoroutineContext)var childJob:Job?= nullval parentJob = launch(Dispatchers.Default) {childJob =  launch(Job()) {delay(200)}delay(300)}println("parentJOb${parentJob }")println("childJob=${childJob }")println("childJOb = parentJOb=${childJob?.parent == parentJob }")}
}

下面的代碼打印結果是什么?

   fun main() {runBlocking {var job1: Job? =nullvar coroutineScope:CoroutineScope? = nullval  job =  launch {job1= this.coroutineContext[Job]coroutineScope = thisdelay(3000)}delay(100)println("coroutineScope === job1=${coroutineScope === job1 }")println("job === job1=${job === job1 }")}
}

coroutineScope === job1=true
job === job1=true

意思是他們三個其實是一個對象

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/79752.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/79752.shtml
英文地址,請注明出處:http://en.pswp.cn/web/79752.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

七、深入 Hive DDL:管理表、分區與洞察元數據

作者:IvanCodes 日期:2025年5月13日 專欄:Hive教程 內容導航 一、表的 DDL 操作 (非創建)二、分區的 DDL 操作三、洞察元數據:SHOW 命令的威力結語:DDL 與 SHOW,Hive 管理的雙翼練習題一、選擇題二、代碼題…

【 Redis | 實戰篇 短信登錄 】

前言: 主要完成了基于Session實現登錄,解決集群的Session共享問題,從而實現了基于Redis來實現共享Session登錄 1.基于Session實現登錄 1.1.發送短信驗證碼 步驟: 前端提交手機號 》校驗手機號 》不符合返回錯誤信息&#xff0…

藍橋杯14屆國賽 合并數列

問題描述 小明發現有很多方案可以把一個很大的正整數拆成若干正整數的和。他采取了其中兩種方案,分別將他們列為兩個數組 {a1,a2,...,an} 和 {b1,b2,...,bm}。兩個數組的和相同。 定義一次合并操作可以將某數組內相鄰的兩個數合并為一個新數,新數的值是…

Doris和Clickhouse對比

目錄 一、Doris和Clickhouse對比1. 底層架構**DorisClickHouse** 2. 運行原理DorisClickHouse 3. 使用場景DorisClickHouse 4. 優缺點對比總結 二、MPP架構和Shared-Nothing 架構對比1. 什么是 MPP 架構?定義特點典型代表 2. 什么是 Shared-Nothing 架構&#xff1f…

niushop單商戶V5多門店版V5.5.0全插件+商品稱重、商家手機端+搭建環境教程

一.系統介紹 【全開源】niushop單商戶V5多門店版V5.5.0版本,我看很多人都想要 商品稱重、商家手機端等插件這套是全插件版本,整合起來本博主也花了不少啦~ Niushop系統是應用thinkphp6開發的完善的電商系統,擁有完善的商品機制,…

內存、磁盤、CPU區別,Hadoop/Spark與哪個聯系密切

1. 內存、磁盤、CPU的區別和作用 1.1 內存(Memory) 作用: 內存是計算機的短期存儲器,用于存儲正在運行的程序和數據。它的訪問速度非常快,比磁盤快幾個數量級。在分布式計算中,內存用于緩存中間結果、存儲…

Jenkins linux安裝

jenkins啟動 service jenkins start 重啟 service jenkins restart 停止 service jenkins stop jenkins安裝 命令切換到自己的下載目錄 直接用命令下載 wget http://pkg.jenkins-ci.org/redhat-stable/jenkins-2.190.3-1.1.noarch.rpm 下載直接安裝 rpm -ivh jenkins-2.190.3-…

RabbitMQ ②-工作模式

RabbitMQ 工作模式 官方提供了七種工作模式 Simple(簡單模式) P:生產者,發布消息到隊列C:消費者,從隊列中獲取消息并消費Queue:消息隊列,存儲消息。 一個生產者,一個…

(2)python開發經驗

文章目錄 1 pyside6加載ui文件2 使用pyinstaller打包 更多精彩內容👉內容導航 👈👉Qt開發 👈👉python開發 👈 1 pyside6加載ui文件 方法1: 直接加載ui文件 from PySide6.QtWidgets import QAp…

【C++】互斥鎖(Mutex)

在C中,互斥鎖(Mutex)是用于線程同步的重要工具,用于保護共享資源,防止多線程同時訪問導致的數據競爭(Data Race)問題。 以下是C中互斥鎖的核心用法和示例: 一、基本互斥鎖 std::mut…

Jsoup與HtmlUnit:兩大Java爬蟲工具對比解析

Jsoup:HTML解析利器 定位:專注HTML解析的輕量級庫(也就是快,但動態頁面無法抓取) 核心能力: DOM樹解析與CSS選擇器查詢 HTML凈化與格式化 支持元素遍歷與屬性提取 應用場景:靜態頁面數據抽…

小白成長之路-vim編輯

文章目錄 Vim一、命令模式二、插入模式3.a:進入插入模式,在當前光標的后一個字符插入![在這里插入圖片描述](https://i-blog.csdnimg.cn/direct/fd293c3832ed49e2974abfbb63eeb5bb.png)4.o: 在當前光標的下一行插入5.i:在當前光標所在字符插入,返回命令模…

[redis進階六]詳解redis作為緩存分布式鎖

目錄 一 什么是緩存 緩存總結板書: 二 使?Redis作為緩存 三 緩存的更新策略 1) 定期?成 2) 實時?成 四 面試重點:緩存預熱,緩存穿透,緩存雪崩 和緩存擊穿 1)緩存預熱 2)緩存穿透 3)緩存雪崩 4)緩存擊穿 五 分布式鎖 板書: 1)什么是分布式鎖 2)分布式鎖的基…

【MySQL】數據表插入數據

個人主頁:Guiat 歸屬專欄:MySQL 文章目錄 1. 插入數據概述1.1 插入數據的重要性1.2 插入數據的基本原則 2. 基本插入語句2.1 INSERT INTO語法2.2 插入多行數據2.3 不指定列名的插入2.4 插入NULL和默認值 3. 高級插入技術3.1 使用子查詢插入數據3.2 IGNOR…

軟考-軟件設計師中級備考 14、刷題 算法

一、考點歸納 1)排序 2、查找 3、復雜度 4、經典問題 0 - 1 背包動態規劃0 - 1 背包問題具有最優子結構性質和重疊子問題性質。通過動態規劃可以利用一個二維數組來記錄子問題的解,避免重復計算,從而高效地求解出背包能裝下的最大價值。分…

【阿里云】阿里云 Ubuntu 服務器無法更新 systemd(Operation not permitted)的解決方法

零、前言 目前正在使用的Ubuntu服務器中,僅阿里云(不止一臺)出現了這個問題,因此我判定是阿里云服務器獨有的問題。如果你的服務器提供商不是阿里云,那么這篇文章可能對你沒有幫助。 如果已經因為升級錯誤導致依賴沖突…

css 點擊后改變樣式

背景: 期望實現效果:鼠標點擊之后,保持選中樣式。 實現思路:在css樣式中,:active 是一種偽類,用于表示用戶當前正在與被選定的元素進行交互。當用戶點擊或按住鼠標時,元素將被激活,此…

采用AI神經網絡降噪算法的語言降噪消回音處理芯片NR2049-P

隨著AI時代來臨.通話設備的環境噪音抑制也進入AI降噪算法時代. AI神經網絡降噪技術是一款革命性的語音處理技術,他突破了傳統單麥克風和雙麥克風降噪的局限性,利用采集的各種日常環境中的噪音樣本進行訓練學習.讓降噪算法具有自適應噪聲抑制功能,可以根…

不用聯網不用編程,PLC通過智能網關快速實現HTTP協議JSON格式與MES等系統平臺雙向數據通訊

智能網關IGT-DSER集成了多種PLC的原廠協議,方便實現各種PLC、智能儀表通過HTTP協議與MES等各種系統平臺通訊對接。PLC內不用編寫程序,設備不用停機,通過網關的參數配置軟件(下載地址)配置JSON文件的字段與PLC寄存器地址等參數即可。 …

如何將兩臺虛擬機進行搭橋

將兩臺虛擬機實現網絡互通(“搭橋”)需配置虛擬網絡,以下是基于 VMware Workstation 和 VirtualBox 的詳細操作指南(以 Windows 系統為例,Linux 原理類似): 一、VMware Workstation 配置&#x…