首页 > 其他分享 >kotlin协程介绍(一)

kotlin协程介绍(一)

时间:2023-02-06 11:06:44浏览次数:36  
标签:协程 name Thread kotlin 介绍 currentThread println 函数

问题背景

我们在kotlin的学习和使用过程中,协程是一个很重要的概念,这个也是java没有的,那么,什么是协程呢? 协程的定义可以将它理解成一种轻量级的线程。我们之前所学习的线程是非常重量级的,它需要依靠操作系统的调度才能实现不同线程之间的切换。使用协程就可以在编程语言的层面实现不同协程之间的切换,大大提升并发编程的运行效率

问题分析

大概了解了协程的概念之后,第二个问题,协程是怎么使用的呢? 1、导入依赖库 想要使用协程功能,需要先在app/build.gradle文件当中添加如下依赖库:

    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1"
    implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1"

2、简单启动一个协程

fun main() {
    GlobalScope.launch {
        println("Coroutines in Thread.currentThread().name" + Thread.currentThread().name)
    }
}

运行结果如下: image.png Global.launch函数每次创建的都是一个顶层协程,这种协程当应用程序运行结束时也会跟着一起结束。刚才的代码所以无法打印出来,就是因为代码块中的代码还没来得及运行,应用程序就结束了。 现在我们让程序延迟一段时间再结束,代码如下所示:

fun main() {
    GlobalScope.launch {
        println("Coroutines in Thread.currentThread().name" + Thread.currentThread().name)
    }
    Thread.sleep(1000)
}

运行结果如下: image.png 这种写法还是存在问题的,如果代码块中的代码在1秒钟之内不能运行结束,那么就会被强制中断。比如下面代码:

fun main() {
    GlobalScope.launch {
        println("Coroutines in Thread.currentThread().name begin" + Thread.currentThread().name)
        delay(1500)
        println("Coroutines in Thread.currentThread().name" + Thread.currentThread().name)
    }
    Thread.sleep(1000)
}

运行结果如下: image.png 协程中代码执行到一半就被强行中止了,这个问题怎么处理呢? 借助runBlocking函数就可以实现这个功能,代码如下:

fun main() {
    runBlocking {
        println("Coroutines in Thread.currentThread().name begin" + Thread.currentThread().name)
        delay(1500)
        println("Coroutines in Thread.currentThread().name" + Thread.currentThread().name)
    }
    Thread.sleep(1000)
}

运行结果如下: image.png 3、创建多个协程 使用launch函数,代码如下:

fun main() {
    runBlocking {
        launch {
            println("launch1")
            delay(1000)
            println("launch1 finished")
        }
        launch {
            println("launch2")
            delay(1000)
            println("launch2 finished")
        }
    }
}

运行结果如下: image.png 可以看到,两个子协程中的日志是交替打印的,说明它们确实是像多线程那样并发运行的。然而这两个子协程实际却运行在同一个线程当中,只是由编程语言来决定如何在多个协程之间进行调度,不需要操作系统参与,这也就使得协程的并发效率会高得多。 不过,随着launch函数中的逻辑越来越复杂,可能你需要将部分代码提取到一个单独的函数中。为此Kotlin提供了一个suspend关键字,使用它可以将任意函数声明成挂起函数,而挂起函数之间都是可以互相调用的,如下所示:

suspend fun printHello(){
    println("hello")
    delay(1000)
}

suspend函数只能在协程中或者另外一个suspend函数中调用,调用suspend函数时,协程会挂起,即从当前的线程脱离,等这个函数执行完毕再切回原线程继续执行。 4、协程取消与超时 一个页面启动了一个协程,当页面关掉时我们需要取消协程,要不然等协程切回主线程更新UI时就会出错,还有一个场景就是我们在做网络请求时,通常需要设置一个超时时间。下面是协程取消的例子,代码如下:

    val job = Job()
    val scope = CoroutineScope(job)
    scope.launch { 
        //处理具体逻辑
    }
    job.cancel()

下面是协程超时的例子,代码如下:

GlobalScope.launch(Dispatchers.Main) {
    var user = doIO()
    Log.v("Tag", "result $user")
}
 
suspend fun doIO(): String? {
    var res = withContext(Dispatchers.IO) {
        withTimeoutOrNull(4000) {
            delay(3000)
            "done"
        }
    }
    return res
}

上面是一个超时的例子,withTimeoutOrNull()函数表示,如果在指定的时间内完成了工作,就返回下面的结果("done"),如果未能完成的话会返回null。 5、async和await 协程在切线程后或者调用suspend函数后,虽然没有阻塞协程所在线程,但协程是被阻塞的(挂起),例如在一个协程内需要做两个不相关的请求,他们执行起来也是串行的,使用async函数即可并行的执行:async函数必须在协程作用域当中才能调用,它会创建一个新的子协程并返回一个Deferred对象,如果我们想要获取async函数代码块的执行结果,只需要调用Deferred对象的await()方法即可,代码如下所示:

fun main() {
    runBlocking {
        val result = async {
            1 + 1
        }.await()
        println(result)
    }
}

运行结果如下: image.png

问题总结

本文主要介绍了部分kotlin中协程的相关概念,包括什么是协程、如果创建一个协程、创建多个协程、协程的取消和定时、以及async等关键字的介绍,有兴趣的同学可以进一步深入研究。

标签:协程,name,Thread,kotlin,介绍,currentThread,println,函数
From: https://blog.51cto.com/baorant24/6038732

相关文章

  • Python并发执行的简易实现:多进程、多线程、协程
    多进程importloggingimporttimefrommultiprocessingimportPoollogging.basicConfig(format='%(asctime)s%(message)s',level=logging.INFO)deff(x):time.sleep(......
  • ME GO小车简单介绍
    怎么使用Mixly软件对MEGO小车初始化?MEGO小车怎么编写程序?怎么控制MEGO小车?……MEGO简介特点及功能:体积小巧集成多种传感器和执行器避障检测、自动巡线、灯光......
  • Dubbo-RPC核心接口介绍
    前言Dubbo源码阅读分享系列文章,欢迎大家关注点赞SPI实现部分Dubbo-SPI机制Dubbo-Adaptive实现原理Dubbo-Activate实现原理DubboSPI-Wrapper注册中心Dubbo-聊聊注册......
  • 自我介绍和未来规划
    这个作业属于哪个课程<班级的链接>这个作业要求在哪里<作业要求的链接>这个作业的目标<以自己最佳的状态优秀完成好,fighting>序言:第一次接触markdown编......
  • 异步编程(协程asyncio)
    协程1.异步非阻塞,asyncio2.异步框架:提升性能tomadofastapidjango3.xasgiaiohttp协程是什么协程是不是计算机提供出来的,程序员自己创建的。​协程(corout......
  • RabbitMQ的使用介绍
    一、RabbitMQ是什么RabbitMQ是一种常用的消息中间件,是基于AMQP协议,采用erlang语言开发的面向消息服务的中间件,是一个独立的系统应用程序,可以管理服务器计算资源和网络通......
  • PHP中 empty() 和 isset() 的区别介绍
    目录二者共同点二者区别1、对于未设置的变量的判断2、对于""(空字符串)的判断3、对于0(作为整数的0)的判断4、对于0.0(作为浮点数的0)的判断5、对于"0"......
  • 数组结构的超简单介绍
    有限个相同类型的变量组成的有序集合叫做数组,其中数组的下标是从0开始的在存储方式上,会创建连续的内存空间存放一组类型相同的数据从0开始是计算效率考虑下面定义一个数......
  • 反序列化类校验部分源码解析 断言 drf之请求 drf之响应 视图组件介绍及两个视图基类
    反序列化类校验部分源码解析(了解)断言drf之请求drf之响应视图组件介绍及两个视图基类基于GenericAPIView+5个视图扩展类昨日内容回顾#1序列化类的......
  • 反序列化类校验部分源码解析、断言、 drf之请求、 drf之响应、视图组件介绍及两个视图
    反序列化类校验部分源码解析、断言、drf之请求、drf之响应、视图组件介绍及两个视图基类、基于GenericAPIView+5个视图扩展类反序列化类校验部分源码解析(了解)#反序列......