【Kotlin】select简介

1 前言

        协程的 select 是一种用于异步操作的选择器,它允许同时等待多个挂起函数的结果,并在其中一个完成时执行相应的操作。

        能够被 select 的事件都是 SelectClause,在 select.kt 中有定义,如下。

public interface SelectBuilder<in R> {public operator fun SelectClause0.invoke(block: suspend () -> R)public operator fun <Q> SelectClause1<Q>.invoke(block: suspend (Q) -> R)public operator fun <P, Q> SelectClause2<P, Q>.invoke(param: P, block: suspend (Q) -> R)public operator fun <P, Q> SelectClause2<P?, Q>.invoke(block: suspend (Q) -> R): Unit = invoke(null, block)...
}public interface SelectClause0 {public fun <R> registerSelectClause0(select: SelectInstance<R>, block: suspend () -> R)
}public interface SelectClause1<out Q> {public fun <R> registerSelectClause1(select: SelectInstance<R>, block: suspend (Q) -> R)
}public interface SelectClause2<in P, out Q> {public fun <R> registerSelectClause2(select: SelectInstance<R>, param: P, block: suspend (Q) -> R)
}internal class SelectBuilderImpl<in R>(private val uCont: Continuation<R>
) : LockFreeLinkedListHead(), SelectBuilder<R>,SelectInstance<R>, Continuation<R>, CoroutineStackFrame
{override fun SelectClause0.invoke(block: suspend () -> R) {registerSelectClause0(this@SelectBuilderImpl, block)}override fun <Q> SelectClause1<Q>.invoke(block: suspend (Q) -> R) {registerSelectClause1(this@SelectBuilderImpl, block)}override fun <P, Q> SelectClause2<P, Q>.invoke(param: P, block: suspend (Q) -> R) {registerSelectClause2(this@SelectBuilderImpl, param, block)}
}

2 select 在 Job 中的应用

         1)应用

fun main() {CoroutineScope(Dispatchers.Default).launch {var job1 = launchJob("job-1", 100)var job2 = launchJob("job-2", 200)var res = select {job1.onJoin { "select: 1" }job2.onJoin { "select: 2" }}println(res) // 打印: select: 1}Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
}suspend fun launchJob(tag: String, delayTime: Long): Job =CoroutineScope(Dispatchers.Default).launch {println("tag")delay(delayTime)}

        打印如下。

tag
tag
select: 1

        2)onJoin 源码

        onJoin 是 Job 中定义的属性。

public val onJoin: SelectClause0

        说明:在调用 job1.onJoin { xxx } 时,等价于调用了 SelectClause0.invoke 函数,也等价于调用了 SelectClause0.registerSelectClause0 函数。

3 select 在 Deferred 中的应用

        1)应用

fun main() {CoroutineScope(Dispatchers.Default).launch {var task1 = asyncTask("task-1", 100)var task2 = asyncTask("task-2", 200)var res = select {task1.onAwait { "select: $it" }task2.onAwait { "select: $it" }}println(res) // 打印: select: task-1}Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
}suspend fun asyncTask(tag: String, delayTime: Long): Deferred<String> =CoroutineScope(Dispatchers.Default).async {delay(delayTime)tag}

        打印如下。

select: task-1

        2)onAwait 源码

        onAwait 是 Deferred 中定义的属性。

public val onAwait: SelectClause1<T>

        说明:在调用 task1.onAwait { xxx } 时,等价于调用了 SelectClause1.invoke 函数,也等价于调用了 SelectClause1.registerSelectClause1 函数。

4 select 在 Channel 中的应用

4.1 onSend

        1)应用

fun main() {var channels = List(2) { Channel<String>() }CoroutineScope(Dispatchers.Default).launch {var res = select {channels[0].onSend("select-1") { "task-1" }channels[1].onSend("select-2") { "task-2" }}println("res=$res") // 打印: res=task-2}receiveTask(200, channels[0])receiveTask(100, channels[1])Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
}fun receiveTask(delayTime: Long, channel: Channel<String>) {CoroutineScope(Dispatchers.Default).launch {delay(delayTime)var element = channel.receive()println("receive: $element")}
}

        打印如下。

receive: select-2
res=task-2

        2)onSend 源码

        onSend 是 Channel 中定义的属性。

public val onSend: SelectClause1<E>

        说明:在调用 channels[0].onSend(xxx) { yyy } 时,等价于调用了 SelectClause2.invoke 函数,也等价于调用了 SelectClause2.registerSelectClause2 函数。

4.2 onReceive

        1)应用

fun main() {var channels = List(2) { Channel<String>() }sendTask("task-1", 200, channels[0])sendTask("task-2", 100, channels[1])CoroutineScope(Dispatchers.Default).launch {var res = select {channels[0].onReceive { "select: $it" }channels[1].onReceive { "select: $it" }}println(res) // 打印: select: task-2}Thread.sleep(1000) // 阻塞当前线程, 避免程序过早结束, 协程提前取消
}fun sendTask(tag: String, delayTime: Long, channel: Channel<String>) {CoroutineScope(Dispatchers.Default).launch {delay(delayTime)channel.send(tag)}
}

        打印如下。

select: task-2

        2)onReceive 源码

        onReceive 是 Channel 中定义的属性。

public val onReceive: SelectClause1<E>

        说明:在调用 channels[0].onReceive { xxx } 时,等价于调用了 SelectClause1.invoke 函数,也等价于调用了 SelectClause1.registerSelectClause1 函数。

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

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

相关文章

【高质量】2024五一数学建模C题保奖思路+代码(后续会更新)

你的点赞收藏是我后续更新的最大动力&#xff01; 一定要点击文末的卡片&#xff0c;那是获取资料的入口&#xff01; 你是否在寻找数学建模比赛的突破点&#xff1f; 作为经验丰富的数学建模团队&#xff0c;我们将为你带来2024 年五一数学建模&#xff08;C题&#xff09;…

react中useReducer如何使用

useReducer 是 React 提供的一个用于状态管理的 Hook&#xff0c;它接收一个 reducer 函数和初始状态作为参数&#xff0c;并返回当前状态以及一个 dispatch 函数。这个 Hook 适用于管理复杂或嵌套的状态对象&#xff0c;它提供了一种更加结构化的更新状态的方法。 useReducer是…

1700java进销存管理系统Myeclipse开发sqlserver数据库web结构java编程计算机网页项目

一、源码特点 java web进销存管理系统是一套完善的java web信息管理系统&#xff0c;对理解JSP java编程开发语言有帮助&#xff0c;系统具有完整的源代码和数据库&#xff0c;系统主要采用B/S模式开发。开发环境为 TOMCAT7.0,Myeclipse8.5开发&#xff0c;数据库为sqlser…

Vue通过下拉框选择字典值,并将对应的label以及value值提交到后端

产品品种从字典中获取 产品性质也是从字典中获取 字典当中的保存 dict_type表 dict_data表 在表单提交的方法中 1.因为做的产品性质是多选&#xff0c;它会以数组的方式提交&#xff0c;所以需要先将Json格式转变为String JSON.stringify(this.form.nature) 2.提交表单&…

【Linux网络编程】DNS、ICMP、NAT技术、代理服务器+网络通信各层协议总结

DNS、ICMP、NAT技术、代理服务器网络通信总结 1.DNS2.ICMP协议2.1ping命令2.2traceroute命令 3.NAT技术4.NAT和代理服务器5.网线通信各层协议总结 点赞&#x1f44d;&#x1f44d;收藏&#x1f31f;&#x1f31f;关注&#x1f496;&#x1f496; 你的支持是对我最大的鼓励&…

【Python】指定正负样本在逻辑回归和随机森林模型训练中的重要性

太多的借口 太多的理由 为了爱情 我也背叛了所有 如果你想离开我 就别再畏畏缩缩 太多的借口 太多的理由 别再问我难过时候怎么过 或许会好好地活 或许会消失无踪 你在乎什么 &#x1f3b5; 陈冠蒲《太多》 在机器学习的分类问题中&#xff0c;正确地指定…

vue3 依赖-组件tablepage-vue3版本1.0.3更新内容

github求⭐ 可通过github 地址和npm 地址查看全部内容 vue3 依赖-组件tablepage-vue3说明文档&#xff0c;列表页快速开发&#xff0c;使用思路及范例-汇总 vue3 依赖-组件tablepage-vue3说明文档&#xff0c;列表页快速开发&#xff0c;使用思路及范例&#xff08;Ⅰ&#…

JAVAEE—servlet的概念及使用,使用servlet接口实现一个表白墙

文章目录 servlet的概念静态页面和动态页面servlet的作用 写出一个servlet程序目录的创建设置smart tomcat编写helloworld servlet的概念 首先我们要搞明白什么是servlet&#xff0c;servlet是一种实现动态页面的技术&#xff0c;他是由tomcat提供给程序员的一组API可以帮助程…

好用的电子文档管理系统应具备哪些功能?

文档是我们工作生活的基本组成部分&#xff0c;但你可能没有注意到花了多少时间处理它们。 良好的电子文档管理可以节省时间并简化整个组织的流程&#xff0c;来进一步了解下吧&#xff01; 文档管理软件的用例 电子文档管理系统,8Manage EDMS,高亚科技 文档管理不仅仅是组…

html中引用视频文件的方式有哪些?

在HTML中引用视频文件的方式有以下几种&#xff1a; 使用 <video> 标签&#xff1a;通过使用 <video> 标签来嵌入视频文件&#xff0c;可以设置视频的大小、播放控件和其他属性。示例代码如下&#xff1a; <video src"video.mp4" controls width&qu…

信息安全实战01_基于AES(CMAC)加密算法脚本开发

本文框架 前言1. 基于AES128的CMAC认证脚本开发1.1 hex文件解析1.2 涉及的Python库1.3 读取待认证的hex数据1.4 计算CMAC1.5 CMAC填充1.6 Chechsum的计算前言 在信息安全中有两个非常重要的应用:安全启动及安全刷新,所谓安全启动即是在用户程序启动前,先进行校验,防止恶意…

【学习笔记二十九】EWM较特殊的业务场景

一、供应商寄售业务相关 1.创建寄售物料、寄售信息记录以及寄售的采购订单 2.创建交货单 3.维护入库交货 行项目里存在C寄售的标识 4.创建上架的仓库任务并确定 查看仓位库存&#xff0c;发现仓位库存里存在寄售标识C以及寄售库存所有方 5.寄售转自有 ①首先MIGO里进行寄…

【吊打面试官系列】Java高并发篇 - Java 中的同步集合与并发集合有什么区别?

大家好&#xff0c;我是锋哥。今天分享关于 【Java 中的同步集合与并发集合有什么区别&#xff1f;】面试题&#xff0c;希望对大家有帮助&#xff1b; Java 中的同步集合与并发集合有什么区别&#xff1f; 同步集合与并发集合都为多线程和并发提供了合适的线程安全的集合&…

C语言-宏定义2.0

无参宏 这些宏没有参数&#xff0c;它们只是简单地将一个特定的文本替换为另一个文本 无参宏意味着使用宏的时候&#xff0c;无需指定任何参数&#xff0c;比如&#xff1a; #define PI 3.14 #define SCREEN_SIZE 800*480*4 int main() {// 在代码中&#xff0c;可以…

【团体程序设计天梯赛】往年关键真题 L2-033 简单计算器 栈 L2-035 完全二叉树的层序遍历 树 详细分析完整AC代码

【团体程序设计天梯赛 往年关键真题 详细分析&完整AC代码】搞懂了赛场上拿下就稳 【团体程序设计天梯赛 往年关键真题 25分题合集 详细分析&完整AC代码】&#xff08;L2-001 - L2-024&#xff09;搞懂了赛场上拿下就稳了 【团体程序设计天梯赛 往年关键真题 25分题合…

微隔离实施五步法,让安全防护转起来

前言 零信任的最核心原则→最小权限 安全的第一性原理→预防 零信任的最佳实践→微隔离 “零信任”这个术语的正式出现&#xff0c;公认是在2010年由Forrester分析师John Kindervag最早提出。时至今日&#xff0c;“零信任”俨然已成安全领域最热门的词汇&#xff0c;做安全…

盛银消费金融2023年年报: 坚持稳中求进、稳中求变

近日&#xff0c;盛银消费金融发布了2023年年报。报告期内&#xff0c;截至报告期末&#xff0c;公司资产总额65.87亿元&#xff0c;增幅12.57%&#xff1b;贷款余额57.92亿元&#xff0c;增幅8.43%&#xff1b;营业收入2.43亿元&#xff0c;增幅36.36%&#xff1b;净利润0.82亿…

想要接触网络安全,应该怎么入门学习?

作为一个网络安全新手&#xff0c;首先你要明确以下几点&#xff1a; 我刚入门网络安全&#xff0c;该怎么学&#xff1f;要学哪些东西&#xff1f;有哪些方向&#xff1f;怎么选&#xff1f;这一行职业前景如何&#xff1f; 其次&#xff0c;如果你现在不清楚学什么的话&…

物联网实战--平台篇之(二)基础搭建

目录 一、Qt工程创建 二、数据库知识 三、通信协议 四、名词定义 本项目的交流QQ群:701889554 物联网实战--入门篇https://blog.csdn.net/ypp240124016/category_12609773.html 物联网实战--驱动篇https://blog.csdn.net/ypp240124016/category_12631333.html 一、Qt工程…

如何使用ChatGPT进行高效的中文到科学英文翻译?

如何使用ChatGPT进行高效的中文到科学英文翻译 在全球化加速的今天&#xff0c;科学交流往往需要跨越语言障碍。特别是在科研领域&#xff0c;有效地将中文研究成果转化为精准的科学英语描述&#xff0c;对于学术发表和国际合作尤为关键。AI翻译工具如ChatGPT可以在这一过程中…