kotlin 協程(Coroutine)

Coroutine(協程)的轉換原理:

在 kotlin 中,Coroution 是一種輕量級的線程管理方式,其轉換原理涉及 狀態機生成掛起函數轉換調度器機制

一、協程的本質:狀態機

kotlin 協程通過 編譯器生成狀態機 實現。(當你編寫一個掛起函數(suspend))或協程體時,編譯器會將其轉換為一個狀態機類。

示例代碼

kotlin

suspend fun fetchData() {val data = loadFromNetwork() // 掛起點 1processData(data)          // 掛起點 2
}
編譯后等價代碼(簡化版)

java

// 編譯器生成的狀態機類
final class FetchDataKt$fetchData$1 extends SuspendLambda implements Function2<Unit, Continuation<? super Unit>, Object> {int label;                // 當前狀態Object result;            // 中間結果String data;              // 局部變量FetchDataKt$fetchData$1(Continuation<? super Unit> completion) {super(2, completion);}@Overridepublic final Object invokeSuspend(Object $result) {this.result = $result;this.label |= Integer.MIN_VALUE;// 根據狀態跳轉到不同代碼段switch (label) {case 0: // 初始狀態// 執行 loadFromNetwork()return loadFromNetwork(this);case 1: // 恢復狀態 1data = (String) result;processData(data);return Unit.INSTANCE;default:throw new IllegalStateException("call to 'resume' before 'invoke' with coroutine");}}
}

二、掛起函數的轉換

掛起函數(suspend)的關鍵在于 保存和恢復執行狀態

  1. 掛起點(Suspension Point):
    當協程遇到掛起函數(如?delay()withContext())時,會:

    • 保存當前狀態(局部變量、執行位置)到狀態機。
    • 返回到調用者(不會阻塞線程)。
  2. 恢復執行
    當掛起條件滿足(如網絡請求完成)時,通過?Continuation.resume()?恢復狀態機:

    • 恢復局部變量和執行位置。
    • 從掛起點繼續執行。

三、協程調度器(CoroutineDispatcher)

協程通過?調度器?決定在哪個線程上執行:

常見調度器
  • Dispatchers.Main:Android 主線程,用于 UI 操作。
  • Dispatchers.IO:IO 優化的線程池,適合網絡 / 文件操作。
  • Dispatchers.Default:CPU 密集型任務的默認線程池。
  • newSingleThreadContext():創建專用單線程。
調度器工作原理
  1. 協程啟動

    GlobalScope.launch(Dispatchers.IO) {val data = fetchData() // 在 IO 線程執行withContext(Dispatchers.Main) {updateUI(data)     // 切換到主線程}
    }
    
  2. 線程切換實現

  • withContext()?是一個掛起函數,會:
  1. 保存當前狀態。
  2. 將任務提交到目標調度器的線程。
  3. 在新線程恢復執行。

四、協程與線程的關系

特性協程線程
創建成本極低(約 2KB 內存)高(約 1MB 棧空間)
調度方式協作式(由協程自己決定何時掛起)搶占式(由操作系統調度)
切換開銷極小(僅狀態機跳轉)高(上下文切換涉及內核操作)
數量限制可創建數百萬個通常限制在數千個
阻塞影響僅阻塞當前協程阻塞整個線程

五、關鍵組件與機制

1. Continuation
  • 協程的核心接口,定義了恢復執行的方法:
    interface Continuation<in T> {val context: CoroutineContextfun resumeWith(result: Result<T>)
    }
    
  • 編譯器會為每個協程生成?Continuation?的實現。
2. Job
  • 協程的生命周期控制器,可用于取消、檢查狀態:
    val job = launch { ... }
    job.cancel() // 取消協程
    
3. CoroutineContext
  • 存儲協程的上下文信息(如調度器、異常處理器):
    val scope = CoroutineScope(Dispatchers.IO + Job())
    

    ??

六、優化與調試建議

  1. 避免阻塞調度器線程

    // 錯誤:在 IO 調度器中執行 CPU 密集型任務
    withContext(Dispatchers.IO) {heavyCalculation() // 應使用 Dispatchers.Default
    }
    
  2. 使用協程作用域(CoroutineScope)
    避免內存泄漏,自動管理協程生命周期:

    class MyViewModel : ViewModel() {fun fetchData() = viewModelScope.launch { ... }
    }
    
  3. 調試工具

    • 使用?runBlocking { ... }?在測試中阻塞主線程。
    • 通過?LoggingInterceptor?記錄協程調度過程。

七、總結

Kotlin 協程通過?狀態機轉換?和?非阻塞掛起機制,實現了高效的線程管理:

  • 編譯器將協程代碼轉換為狀態機,保存執行狀態。
  • 調度器決定協程在哪個線程執行,支持靈活切換。
  • 相比傳統線程,協程大幅降低資源消耗,提升并發能力。

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

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

相關文章

線性變換之維數公式(秩-零化度定理)

秩數-零化度定理(rank-nullity theorem) 目錄 1. (映射)零空間(線性映射或變換的核)(null-space或nullspace) 2. 跨度(或開度)(span) 3. (線性映射的)零化度(nullity) 4. 線性變換的維數公式(秩數-零化度定理)(rank-nullity theorem) 5. 函數的上域(codomain) 1…

Spring Cloud Gateway 實戰:網關配置與 Sentinel 限流詳解

Spring Cloud Gateway 實戰&#xff1a;網關配置與 Sentinel 限流詳解 在微服務架構中&#xff0c;網關扮演著統一入口、負載均衡、安全認證、限流等多種角色。Spring Cloud Gateway 是 Spring Cloud 官方推出的新一代網關組件&#xff0c;相比于第一代 Netflix Zuul&#xff…

JAVA-常用API(二)

目錄 1.Arrays 1.1認識Arrays 1.2Arrays的排序 2.JDK8的新特性&#xff1a;Lambda表達式 2.1認識Lambda表達式 2.2用Lambda表達式簡化代碼、省略規則 3.JDK8的新特性&#xff1a;方法引用&#xff08;進一步簡化Lambda表達式&#xff09; 3.1 靜態方法引用 3.2 實例方法引…

深入理解PHP的命名空間

命名空間是PHP 5.3引入的一個特性&#xff0c;它的主要目的是解決在大型應用程序中可能出現的名稱沖突問題。在沒有命名空間的情況下&#xff0c;如果兩個不同的庫或模塊定義了相同名稱的函數或類&#xff0c;那么在使用這些庫或模塊的時候就會引發沖突。為了解決這個問題&…

SwiftUI學習筆記day5:Lecture 5 Stanford CS193p 2023

SwiftUI學習筆記day5:Lecture 5 Stanford CS193p 2023 課程鏈接&#xff1a;Lecture 5 Stanford CS193p 2023代碼倉庫&#xff1a;iOS課程大綱&#xff1a; Enum 定義&#xff1a;enum MyType { … }關聯值&#xff1a;case drink(name: String, oz: Int)匹配&#xff1a;switc…

idea 報錯:java: 非法字符: ‘\ufeff‘

idea 報錯&#xff1a;java: 非法字符: ‘\ufeff‘ 解決方案&#xff1a;

數據結構與算法之美:圖

Hello大家好&#xff01;很高興我們又見面啦&#xff01;給生活添點passion&#xff0c;開始今天的編程之路&#xff01; 我的博客&#xff1a;<但凡. 我的專欄&#xff1a;《編程之路》、《數據結構與算法之美》、《題海拾貝》、《C修煉之路》 歡迎點贊&#xff0c;關注&am…

SpringBoot -- 熱部署

9.SpringBoot 熱部署&#xff08;自動重啟&#xff09; 在實際開發過程中&#xff0c;每次修改代碼就得將項目重啟&#xff0c;重新部署&#xff0c;對于一些大型應用來說&#xff0c;重啟時間需要花費大量的時間成本。對于一個后端開發者來說&#xff0c;重啟過程確實很難受啊…

HarmonyOS 5瀏覽器引擎對WebGL 2.0的支持如何?

以下是HarmonyOS 5瀏覽器引擎對?WebGL 2.0?支持的詳細技術分析&#xff1a; 一、核心支持能力 ?系統能力聲明 HarmonyOS 5 瀏覽器引擎通過 SystemCapability.Graphic.Graphic2D.WebGL2 提供對 WebGL 2.0 的底層支持 支持的關鍵特性包括&#xff1a; OpenGL ES 3.0 特性…

Class1線性回歸

Class1線性回歸 買房預測 要根據歷史數據來預測一套房子的價格。你發現影響房價的因素有很多&#xff0c;于是你決定使用線性回歸模型來預測房價。 影響房價的因素如下&#xff1a; 房屋面積&#xff08;平方米&#xff09; 房齡&#xff08;年&#xff09; 離地鐵站的距離&a…

Vue.js 3:重新定義前端開發的進化之路

Vue.js 3&#xff1a;重新定義前端開發的進化之路 引言&#xff1a;一場醞釀已久的革新 2020年9月18日&#xff0c;Vue.js團隊以代號"One Piece"正式發布3.0版本&#xff0c;這不僅是框架發展史上的重要里程碑&#xff0c;更是前端工程化領域的一次革命性突破。歷經…

Unity性能優化-渲染模塊(1)-CPU側(1)-優化方向

Unity 中渲染方面的優化大致可以劃分為以下幾塊核心內容&#xff1a; CPU 優化 (減少 Draw Calls 和 CPU 瓶頸) GPU 優化 (減少像素著色和 GPU 瓶頸) 內存和顯存優化 (Resource Management) 光照優化 (Lighting & Global Illumination) 這四個方面是相互關聯的。一個方…

AI矢量圖與視頻無痕修復:用Illustrator與After Effects解鎖創作新維度

最近因一個項目&#xff0c;有機會深度體驗了奧地利Blueskyy藝術學院授權的Adobe教育版全家桶&#xff0c;過程中發現了不少令人驚喜的“黑科技”&#xff0c;很想和大家分享這份發掘寶藏的喜悅。一句話總結這次體驗&#xff1a;慷慨且穩定。比如&#xff0c;它每周提供高達150…

Maven Javadoc 插件使用詳解

Maven Javadoc 插件使用詳解 maven-javadoc-plugin 是 Maven 項目中用于生成 Java API 文檔的標準插件&#xff0c;它封裝了 JDK 的 javadoc 工具&#xff0c;提供了更便捷的配置和集成方式。 一、基本使用 1. 快速生成 Javadoc 在項目根目錄執行以下命令&#xff1a; bas…

Apache Kafka 面試應答指南

Apache Kafka 核心知識詳解與面試應答指南 一、Apache Kafka 概述 Apache Kafka 作為一款分布式流處理框架,在實時構建流處理應用領域發揮著關鍵作用。其最廣為人知的核心功能,便是作為企業級消息引擎被眾多企業采用。 二、消費者組 (一)定義與原理 消費者組是 Kafka 獨…

在NVIDIA Jetson和RTX上運行Google DeepMind的Gemma 3N:多模態AI的邊緣計算革命

在NVIDIA Jetson和RTX上運行Google DeepMind的Gemma 3N&#xff1a;多模態AI的邊緣計算革命 文章目錄 在NVIDIA Jetson和RTX上運行Google DeepMind的Gemma 3N&#xff1a;多模態AI的邊緣計算革命引言&#xff1a;多模態AI進入邊緣計算時代文章結構概覽 第一章&#xff1a;Gemma…

iOS打包流程中的安全處理實踐:集成IPA混淆保護的自動化方案

隨著iOS應用上線節奏的加快&#xff0c;如何在持續集成&#xff08;CI&#xff09;或交付流程中嵌入安全處理手段&#xff0c;成為開發團隊構建自動化發布鏈路時不可忽視的一環。特別是在App已經完成構建打包&#xff0c;準備分發前這一階段&#xff0c;對IPA進行結構層面的加固…

FFmpeg進行簡單的視頻編輯與代碼寫法實例

使用 FFmpeg 進行簡單的視頻編輯非常強大。它是一個命令行工具&#xff0c;雖然一開始可能看起來有點復雜&#xff0c;但掌握了基本命令后會非常有用。 以下是一些常見的簡單視頻編輯操作及其 FFmpeg 命令&#xff1a; 1. 剪切視頻 如果你想從一個視頻中剪切出一段&#xff0…

如何使用免費軟件寫論文?六個免費論文生成軟件使用指南

在學術寫作中&#xff0c;利用AI技術和免費的寫作工具可以極大地提高效率&#xff0c;尤其對于需要處理大量文獻、結構化寫作的論文來說&#xff0c;使用合適的軟件能節省時間&#xff0c;提升論文質量。這里為您推薦六個免費的論文生成軟件&#xff0c;并提供使用指南&#xf…

大數據系統架構實踐(二):Hadoop集群部署

大數據系統架構實踐&#xff08;二&#xff09;&#xff1a;Hadoop集群部署 文章目錄 大數據系統架構實踐&#xff08;二&#xff09;&#xff1a;Hadoop集群部署一、Hadoop簡介二、部署前準備三、部署Hadoop集群1. 下載并解壓安裝包2. 配置hadoop-env.sh3. 配置core-site.xml4…