Kotlin 进阶版 协程

kotlin是协程的一种实现

  1. Dispatchers.IO:适用于执行磁盘或网络 I/O 操作的调度器,例如文件读写、网络请求等。在 Android 中,Dispatchers.IO 会使用一个专门的线程池来处理这些操作,以防止阻塞主线程。

  2. Dispatchers.Main:适用于处理与 UI 相关的操作的调度器,例如更新 UI 界面、响应用户输入等。在 Android 中,Dispatchers.Main 通常会将协程切换到主线程执行,确保 UI 操作在主线程中进行。

  3. Dispatchers.Unconfined:不对协程的执行环境做任何限制,使用该调度器时,协程将在调用它的线程中执行,直到遇到挂起函数为止,之后会在恢复执行时继续在之前的线程中执行。

  4. Dispatchers.Default:适用于执行 CPU 密集型任务的调度器,例如算法计算、数据处理等。Dispatchers.Default 在 Android 中会使用一个共享的线程池来处理这些任务,以便在多个协程之间进行合理的调度。

 

package com.tiger.kotlincoroutine.coroutineimport kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContextfun main() {//IO线程  超大密集的计算 Default/*** IO* Default* Main**/CoroutineScope(Dispatchers.IO).launch {test()
//        withContext(Dispatchers.Main){
//
//        }}println("主线程")Thread.sleep(2000)
}/*** 协程代码块*/
suspend fun test() {println("协程开始")delay(1000)println("协程结束")
}

1.runBlocking

package com.tiger.kotlincoroutine.coroutineimport kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlockingfun main() {println("hello")//如果给的参数第一个为空,那么它会去找到这个协程外面调用它的这个线程 一般在写Test的时候才用一下 阻塞式协程val i = runBlocking (Dispatchers.IO){//如果制定了了调度器,它会被分配到另一个线程上面执行 ,但也可以阻塞当前线程println(Thread.currentThread().name)//这个协程会阻塞当前线程 同步执行delay(2000)1}println(Thread.currentThread().name)println("world $i ")
}

package com.tiger.kotlincoroutine.coroutineimport kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlockingfun main() {println("hello")//如果给的参数第一个为空,那么它会去找到这个协程外面调用它调度器 一般在写Test的时候才用一下 阻塞式协程//会等里面所有的协程执行完了,才会释放主线程val i = runBlocking (Dispatchers.IO){//如果制定了了调度器,它会被分配到另一个线程上面执行 ,但也可以阻塞当前线程println(Thread.currentThread().name)println(this)//this :BlockingCoroutine 可以再次开启一个协程val job = this.launch {//这个开启的协程不会阻塞当前线程,异步println(//没有指定 ,他会默认继承上面所在的调度器 被这个调度器管理的线程池的线程去执行Thread.currentThread().name)delay(5200)}println(job.isActive)println(job.cancel())println(job.isActive)println("延迟了吗")//这个协程会阻塞当前线程 同步执行delay(2000)1}println(Thread.currentThread().name)println("world $i ")/*** 总结* IO 网络请求 数据库* default 密集型数据处理操作 数据计算* main UI操作**/
}

 

package com.tiger.kotlincoroutine.coroutineimport kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContextfun main() {println("hello")val i = runBlocking (Dispatchers.IO){request{//手动切换到UI线程里withContext(Dispatchers.Main){//修改UI}}}println("world $i")
}suspend fun request(finish:suspend ()->Unit){delay(3000)println("网络请求成功")finish()
}

好处:不会出现在其他的线程里出现UI报错的问题了

2.GlobalScope

package com.tiger.kotlincoroutine.coroutineimport kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launchfun main() {val launch = GlobalScope.launch { //全局指的是整个程序的生命周期 就算Activity销毁了这个GlobalScope还是存在的// 这样可能会造成一些奇怪的问题delay(3000)println("hello")}//这不是阻塞当前线程的一个协程操作val launch1 = GlobalScope.launch {}println(launch===launch1)//不能调用cancel 方法,因为作用域是整个生命周期的,不能由我们来管理while (true);
}

3.CoroutineScope

package com.tiger.kotlincoroutine.coroutineimport kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.cancel
import kotlinx.coroutines.delay
import kotlinx.coroutines.launchfun main() {//推荐使用这个  不是全局的val coroutineScope1 = CoroutineScope(Dispatchers.Default)coroutineScope1.launch {delay(3000)println("结束")}coroutineScope1.launch {delay(3000)println("结束")}coroutineScope1.cancel() //可以手动进行取消,不会涉及到全局 整个程序的生命周期Thread.sleep(4000)println("主线程结束")
}

4.Launch分析

4.1 第一个参数 context: CoroutineContext

package com.tiger.kotlincoroutine.coroutineimport kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.Jobimport kotlinx.coroutines.launch
import kotlinx.coroutines.newCoroutineContext
import kotlinx.coroutines.runBlocking
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext@OptIn(ExperimentalStdlibApi::class)
fun main() {val runBlocking = runBlocking {val launch = this.launch(Dispatchers.Default) {println(this.coroutineContext.get(CoroutineDispatcher).toString())//拿到调度器信息}println(launch)launch}//是同一个对象println(runBlocking)}

package com.tiger.kotlincoroutine.coroutineimport kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.CoroutineName
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.InternalCoroutinesApi
import kotlinx.coroutines.Jobimport kotlinx.coroutines.launch
import kotlinx.coroutines.newCoroutineContext
import kotlinx.coroutines.runBlocking
import kotlin.coroutines.CoroutineContext
import kotlin.coroutines.EmptyCoroutineContext@OptIn(ExperimentalStdlibApi::class)
fun main() {val runBlocking = runBlocking(Dispatchers.IO) {val launch = this.launch (Dispatchers.Default){println(this.coroutineContext.get(CoroutineDispatcher).toString())//拿到调度器信息}println(launch)launch}//是同一个对象println(runBlocking)}

 

4.2 第二个参数 start:CoroutineStart

 

  1. default 是协程默认的启动方式  由默认协程调度去调度 决定在哪一个线程上面执行
val runBlocking = runBlocking(Dispatchers.IO) {val launch = this.launch{println("hello")delay(1000)println("end")}//异步就会走到下面,end不执行launch.cancel()}//是同一个对象

2. ATOMIC

    val runBlocking = runBlocking(Dispatchers.IO) {val launch = this.launch(start = CoroutineStart.ATOMIC){//ATOMIC是一个立即启动的过程 把执行此协程的优先级调上去println("hello")delay(1000)println("end")}//异步就会走到下面,end不执行launch.cancel()}//是同一个对象

3.LAZY 可以自己控制何时启动

 val runBlocking = runBlocking(Dispatchers.IO) {val launch = this.launch(start = CoroutineStart.LAZY){//LAZY 可以自己控制何时启动println("hello")delay(1000)println("end")}println("先打印,在启动")//异步就会走到下面,end不执行launch.start()}//是同一个对象

5. async详解

  this.async(Dispatchers.Default, start = CoroutineStart.DEFAULT){println("进来异步了")delay(1000)println("被卡住了")}

1.获取值方法1

package com.tiger.kotlincoroutine.coroutineimport kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.delayfun main() {val coroutineScope = CoroutineScope(Dispatchers.Default)val async = coroutineScope.async(Dispatchers.Default, start = CoroutineStart.DEFAULT) {println("进来异步了")delay(1000)println("被卡住了")"协程异步返回值"}Thread.sleep(3000)val completed = async.getCompleted()println(completed)
}
package com.tiger.kotlincoroutine.coroutineimport kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlockingfun main() {runBlocking {val async = this.async {test1()}for (i in 0..10) {println("hello $i")}val await = async.await()println(await)}}suspend fun test1():Int{println("执行中")delay(3000)return 100
}

6.select函数 与 onAwait方法

package com.tiger.kotlincoroutine.coroutineimport kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.CoroutineStart
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.async
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.selects.selectfun main() {runBlocking {val d = this.async {delay(2000)test1(1)}//同时启动的val c = this.async {test1(2)}//同时启动的//泛型是协程返回的类型//select可以等待多个协程的结束//select会阻塞当前的线程println(select<String> {c.onAwait.invoke {"c"  //it是协程返回值}d.onAwait.invoke {"d"}//谁先执行结束就返回谁})println("end")}}suspend fun test1(item:Int):Int{println("执行中$item")delay(3000)return 100
}

7. withContenxt

package com.tiger.kotlincoroutine.coroutineimport kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext@OptIn(ExperimentalStdlibApi::class)
fun main() {runBlocking(Dispatchers.IO) {println(coroutineContext.get(CoroutineDispatcher).toString())val withContext = withContext(Dispatchers.Default) {//会对协程有一个阻塞  挂起就是阻塞的意思delay(2000)println(coroutineContext.get(CoroutineDispatcher).toString())//返回值就是lamda最后一行 ,并且结束以后会回到之前的那个协程上面继续执行"withContext result"}println(withContext)println(coroutineContext.get(CoroutineDispatcher).toString())}
}

package com.tiger.kotlincoroutine.coroutineimport kotlinx.coroutines.CoroutineDispatcher
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import kotlinx.coroutines.withContext@OptIn(ExperimentalStdlibApi::class)
fun main() {//如果不想阻塞当前协程,那就重新开一个runBlocking(Dispatchers.IO) {println(coroutineContext.get(CoroutineDispatcher).toString())launch {val withContext = withContext(Dispatchers.Default) {//会对协程有一个阻塞  挂起就是阻塞的意思delay(2000)println(coroutineContext.get(CoroutineDispatcher).toString())//返回值就是lamda最后一行 ,并且结束以后会回到之前的那个协程上面继续执行"withContext result"}println(withContext)}println(coroutineContext.get(CoroutineDispatcher).toString())}
}

8.suspend关键字

协程就是任务代码块,有调度器进行线程分配执行此代码块,可以公用一个线程,异步执行代码块,也可以不是一个线程执行.

suspend 声明一个挂起函数,可以阻塞当前协程去执行代码块里的内容,主要是针对协程的。

因为 Thread.sleep 是停止线程的,协程是在线程上面跑的。

delay是延迟当前协程,不停线程,其他协程在此线程上面跑的话,那么都会被停止

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/695722.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ALINX黑金AXU3EGB 开发板用户手册 CAN接口信号方向标识错误说明

如上篇文章 CAN收发器 SN65HVD232 的D R引脚方向是 D是输入&#xff0c;R是输出。 https://blog.csdn.net/zhengwenbang/article/details/136151668?spm1001.2014.3001.5501 因此 ALINX黑金AXU3EGB 用户手册 Page 43页 图 3-10-1 PS 端 CAN 收发芯片的连接示意图&#xff0c;…

刚开的抖店怎样推广?找主播带货,积累资源/渠道,拉动自然流量成交

我是王路飞。 2024年&#xff0c;依旧有很多人想入局抖音小店。 刚复工没几天&#xff0c;我就已经收到好多粉丝朋友的私信了&#xff0c;纷纷表示自己已经开通了抖店了&#xff0c;但是不会运营&#xff0c;现在新店应该怎样进行推广呢&#xff1f; 这篇内容就给你们详细说…

玩转网络抓包利器:Wireshark常用协议分析讲解

Wireshark是一个开源的网络协议分析工具&#xff0c;它能够捕获和分析网络数据包&#xff0c;并以用户友好的方式呈现这些数据包的内容。Wireshark 被广泛应用于网络故障排查、安全审计、教育及软件开发等领域。关于该工具的安装请参考之前的文章&#xff1a;地址 &#xff0c;…

CVE-2024-0918 TEW-800MB RCE漏洞分析

漏洞描述 固件版本为1.0.1.0的TEW-800MB路由器存在命令注入漏洞。如果攻击者获得了web管理权限&#xff0c;他们可以将命令注入到httpd未知函数中的post请求参数DeviceURL中&#xff0c;从而获得shell权限。。 参考链接 TEW-800MB (notion.site)https://warp-desk-89d.notio…

【嵌入式学习】QT-Day2-Qt基础

1> 思维导图 https://lingjun.life/wiki/EmbeddedNote/20QT 2>登录界面优化 使用手动连接&#xff0c;将登录框中的取消按钮使用qt4版本的连接到自定义的槽函数中&#xff0c;在自定义的槽函数中调用关闭函数 将登录按钮使用qt5版本的连接到自定义的槽函数中&#xff…

LWM(LargeWorldModel)大世界模型-可文字可图片可视频-多模态LargeWorld-详细安装记录

说明 Large World Model&#xff08;LWM&#xff09;是一个通用的大环境多模态自回归模型&#xff0c;它利用了一个技术名为RingAttention&#xff0c;通过在大型的多样化视频和图书数据集上的训练&#xff0c;实现了对语言、图像和视频的理解与生成能力。 在github上已有4.2k…

Spring Boot与Netty:构建高性能的网络应用

点击下载《Spring Boot与Netty&#xff1a;构建高性能的网络应用》 1. 前言 本文将详细探讨如何在Spring Boot应用中集成Netty&#xff0c;以构建高性能的网络应用。我们将首先了解Netty的原理和优势&#xff0c;然后介绍如何在Spring Boot项目中集成Netty&#xff0c;包括详…

JAVA高并发——单例模式和不变模式

文章目录 1、探讨单例模式2、不变模式 由于并行程序设计比串行程序设计复杂得多&#xff0c;因此我强烈建议大家了解一些常见的设计方法。就好像练习武术&#xff0c;一招一式都是要经过学习的。如果自己胡乱打&#xff0c;效果不见得好。前人会总结一些武术套路&#xff0c;对…

体验LobeChat搭建私人聊天应用

LobeChat是什么 LobeChat 是开源的高性能聊天机器人框架&#xff0c;支持语音合成、多模态、可扩展的&#xff08;Function Call&#xff09;插件系统。支持一键免费部署私人 ChatGPT/LLM 网页应用程序。 地址&#xff1a;https://github.com/lobehub/lobe-chat 为什么要用Lobe…

OpenAI Sora引领AI跳舞视频新浪潮:字节跳动发布创新舞蹈视频生成框架

OpenAI的Sora已经引起广泛关注&#xff0c;预计今年AI跳舞视频将在抖音平台上大放异彩。下面将为您详细介绍一款字节跳动发布的AI视频动画框架。 技术定位&#xff1a;这款框架采用先进的diffusion技术&#xff0c;专注于生成人类舞蹈视频。它不仅能够实现人体动作和表情的迁移…

2.21学习总结

1.【模板】ST 表 2.Balanced Lineup G 3.景区导游 4.最近公共祖先&#xff08;LCA&#xff09; 倍增思想&#xff1a;主要用于LCA问题&#xff0c;RMQ问题。在进行 递推 时&#xff0c;如果 状态空间很大&#xff0c;通常的 线性递推 无法满足 时间 与 空间复杂度 的要求&…

Chrome浏览器安装Axure-Chrome-Extension插件

Chrome浏览器打开Axure生成的HTML静态文件页面时&#xff0c;会显示如下图AXURE RP EXTENSION FOR CHROME&#xff0c;这是因为Chrome浏览器没有安装Axure插件Axure-Chrome-Extension导致的。 解决方法&#xff1a; 插件下载地址&#xff1a;https://download.csdn.net/downlo…

通过盲注脚本复习sqllabs第46关order by 注入

在MySQL支持使用ORDER BY语句对查询结果集进行排序处理&#xff0c;使用ORDER BY语句不仅支持对单列数据的排序&#xff0c;还支持对数据表中多列数据的排序。语法格式如下 select * from 表名 order by 列名(或者数字) asc&#xff1b;升序(默认升序) select * from 表名 or…

交换瓶子【第七届】【省赛】【A组】

题目描述 有N个瓶子&#xff0c;编号 1 ~ N&#xff0c;放在架子上。 比如有5个瓶子&#xff1a; 2 1 3 5 4 要求每次拿起2个瓶子&#xff0c;交换它们的位置。 经过若干次后&#xff0c;使得瓶子的序号为&#xff1a; 1 2 3 4 5 对于这么简单的情况&#xff0c;显然&#…

Java练习(第3天)使用StringJoiner类进行字符串连接

一、问题描述 给定2个或多个字符串&#xff0c;将其连接成为一个字符串&#xff0c;并输出连接后字符串的长度。字符串之间用逗号或引号分隔。 样例输入1&#xff1a; Ram Shyam 样例输出1&#xff1a; Ram,Shyam 9 样例输入2&#xff08;要求接在输出1之后&#xff09;:…

C#_索引器

索引器的作用&#xff1a;令对象可像数组一般被索引 索引器 internal class TestClass {public int[] arr { 1, 2, 3, 4, 5 };public string this[int index] // 前者为返回类型&#xff0c;后者为索引类型// 返回类型代表get函数的返回值类型、set函数的value类型&#xff0…

(done) 什么是正定矩阵?Positive Definite Matrices

正定矩阵的定义&#xff1a;https://baike.baidu.com/item/%E6%AD%A3%E5%AE%9A%E7%9F%A9%E9%98%B5/11030459 正定矩阵的作用、验证视频&#xff1a;https://www.bilibili.com/video/BV1Ag411M76G/?spm_id_from333.337.search-card.all.click&vd_source7a1a0bc74158c6993c…

下一代自动化爬虫神器--playwright,所见即所得,不用逆向不要太香!!!

文章目录 1.Playwright介绍2.与 Selenium 和 pyppeteer 相比&#xff0c;Playwright 具有以下几个区别和优势3.在爬虫中使用 Playwright 的好处4.环境安装5.屏幕录制6.保留记录cookie信息7.playwright代码编写详解1.第一个Playwright脚本&#xff08;1&#xff09;同步模式&…

【鼎捷数字化生意经】总说数字化转型?!怎么做才能带来远超你的想象的经济效益呢?他们来告诉你!

编者按&#xff1a; 转型一直在提&#xff0c;2018—2023年&#xff0c;实现数字化转型的企业仅占中国企业的10%&#xff0c;其中实现领军重塑的企业仅占2%。数据看起来并没有那么乐观&#xff01; 新竞争格局下&#xff0c;企业需要直面挑战&#xff0c;定义新前沿&#xff0…

C++动态分配内存知识点!

个人主页&#xff1a;PingdiGuo_guo 收录专栏&#xff1a;C干货专栏 大家好呀&#xff0c;又是分享干货的时间&#xff0c;今天我们来学习一下动态分配内存。 文章目录 1.动态分配内存的思想 2.动态分配内存的概念 2.1内存分配函数 2.2动态内存的申请和释放 2.3内存碎片问…