Kotlin在协程中使用Select表达式选择最快结果

学更好的别人,

做更好的自己。

——《微卡智享》

20162af2c577eed6008d04057c25cb47.jpeg

本文长度为1239,预计阅读4分钟

前言

Kotlin在1.6时增加了Select的表达式,可以同时等待多个挂起函数,并选择第一个可用的。其实就是说在并行的运算中,直接返回最快的结果。

2f2884f518e57be119475cb8209fe460.png

返回最快的结果在哪些场景中应用?

A

其实这个使用的场景也很多,例如我们的APP中获取商品信息,使用串行的方式一般流程是先查找本地数据库,如果没有再请求网络查找信息,而如果改为并行查找,两个同时查找,如果本地存在,速度肯定很快就返回了,不存在也可以快速获取到网络的信息。

再就是像我以前《实测|A*寻路与JPS寻路同一地图运行效率》路径规划算法中,在小的地图里面A*算法和JPS算法速度差不多,而复杂的地图中,JPS要比A*算法快很多倍,所以这里可以直接采用并行处理,获取最快的路径规划。

所以遇到类似这样的情况都可以采用返回最快结果的方式处理。

Select的使用

b3bcfb5097d36549297126482d43212b.png

微卡智享

使用协程中的Select,可以监听async,返回到第一个收到的结果,其架构如下图:

49261622aa10cc2e7b6d1df0c25df1d6.png

代码

package pers.vaccae.channeldemo


import kotlinx.coroutines.*
import kotlinx.coroutines.selects.select




suspend fun getValue(millis: Long): String {
    delay(millis)
    return "Vaccae usetime:${millis}ms"
}


fun main() {
    runBlocking {
        val test1 = async { getValue(100) }
        val test2 = async { getValue(200) }


        val str = select<String> {
            test1.onAwait { rtnvalue -> "test1 ${rtnvalue}" }
            test2.onAwait { rtnvalue -> "test2 ${rtnvalue}" }
        }
        println("str结果:${str}")


        val str2 = select<String> {
            async { getValue(300) }
                .onAwait { rtnvalue -> "test3 ${rtnvalue}" }


            async { getValue(150) }
                .onAwait { rtnvalue -> "test4 ${rtnvalue}" }
        }
        println("str2结果:${str2}")
    }
}

01

壹伴编辑器

a562bc6d4ff5c7987308aa123cc506ab.png

定义一个挂起函数,输入参数为等待时间,用于测试优先返回的结果。

02

两次测试

10cd9df61df67545f7bf8f63bc081989.png

做了两次测试,因为前面的挂起函数返回的是String类型,所以Select<T>泛型就是String类型,我们做了两次测试,第一次输入的延时为100毫秒和200毫秒,第二次是300毫秒和150毫秒,然后我们看一下运行结果。

26b49fa0df65cca39bcdf8687f9c94a7.png

从上图中可以看到,返回的就是最快的结果,而且用Select的代码非常简洁,如果使用传统的方式,一般会加一个公共变量boolean类型的,先求出结果的修改其boolean值为true,并暂存结果,其余的判断为true后不再输出结果了,这样的方式是求出的最快的返回,但是并行的时间还是要等所有的结果出来,而用Select后可以大大节省时间。

02f07fcd0d29d746fa35efd531bd0a80.png

7e0f86ef9ded4b28ebf45a529f3aa999.png

往期精彩回顾

57940ca962999c265164c197620cb1d8.jpeg

Android画中画(PIP)进阶---Action按钮的使用


0eadc47bf3cc392bd730b32fac9f00df.jpeg

Android画中画(PIP)模式使用


ca5125707ad14436fe964ff7e0b6a446.jpeg

C++ OpenCV手动截取图像做透视变换


猜你喜欢

转载自blog.csdn.net/Vaccae/article/details/127743069