首页 > 编程语言 >Kotlin 并发编程之"协程"

Kotlin 并发编程之"协程"

时间:2022-12-16 11:06:55浏览次数:61  
标签:协程 Kotlin 编程 kotlinx coroutines println async


Kotlin协程简介

 

Kotlin, as a language, provides only minimal low-level APIs in its standard library to enable various other libraries to utilize coroutines. Unlike many other languages with similar capabilities, ​​async​​​ and ​​await​​ are not keywords in Kotlin and are not even part of its standard library. Moreover, Kotlin's concept of suspending function provides a safer and less error-prone abstraction for asynchronous operations than futures and promises.

​kotlinx.coroutines​​​ is a rich library for coroutines developed by JetBrains. It contains a number of high-level coroutine-enabled primitives that this guide covers, including ​​launch​​​, ​​async​​ and others.

This is a guide on core features of ​​kotlinx.coroutines​​ with a series of examples, divided up into different topics.

In order to use coroutines as well as follow the examples in this guide, you need to add a dependency on ​​kotlinx-coroutines-core​​ module.

[ https://kotlinlang.org/docs/reference/coroutines/coroutines-guide.html ]

 

协程是一个轻量级的线程。

Kotlin 中的协程的实现原理是:   coroutine == continuation + coroutine scope.(关于这个continuation 和 coroutine scope 我们会在后面的文章中介绍.)

 

 

想要使用 Kotlin 协程,需要单独添加依赖:

 

compile group: 'org.jetbrains.kotlinx', name: 'kotlinx-coroutines-core', version: '1.2.2'


 

先用一个官方的demo,直观认识一下协程:

 

import kotlinx.coroutines.*
fun main() {
GlobalScope.launch { // launch a new coroutine in background and continue
delay(1000L) // non-blocking delay for 1 second (default time unit is ms)
println("World!") // print after delay
}
println("Hello,") // main thread continues while coroutine is delayed
Thread.sleep(2000L) // block main thread for 2 seconds to keep JVM alive
}

输出:

 

Hello, World!

 

Kotlin帮我们去完成线程的调度。

而这里GlobalScope.launch就是创建一个协程环境并且启动一个协程。

 

协程上下文包括了一个 协程调度器,它确定了相应的协程在执行时使用一个或多个线程。协程调度器可以将协程的执行局限在指定的线程中,调度它运行在线程池中或让它不受限的运行。

 

其中, GlobalScope 继承了 CoroutineScope:

 

* A global [CoroutineScope] not bound to any job.
*
* Global scope is used to launch top-level coroutines which are operating on the whole application lifetime
* and are not cancelled prematurely.
* Another use of the global scope is operators running in [Dispatchers.Unconfined], which don't have any job associated with them.
*
* Application code usually should use an application-defined [CoroutineScope]. Using
* [async][CoroutineScope.async] or [launch][CoroutineScope.launch]
* on the instance of [GlobalScope] is highly discouraged.


 

 

我们再写一个稍微丰富一点的例子:

package com.kotlin.notes.coroutine
import kotlinx.coroutines.GlobalScope
import kotlinx.coroutines.delay
import kotlinx.coroutines.launch
import kotlinx.coroutines.runBlocking
import java.lang.Thread.sleep
class CoroutineDemo {
fun doSomething() {
for (i in 0..5) {
println(i)
sleep(1000)
}
println("doSomething done")
}
suspend fun suspendDoSomething() {
for (i in 0..5) {
println(i)
delay(1000)
}
}
}
fun main() = runBlocking {
val d = CoroutineDemo()
d.doSomething()
val job = GlobalScope.launch {
d.suspendDoSomething()
}
println("suspendDoSomething done?")
job.join()
println("suspendDoSomething done!")
}

输出:

0
1
2
3
4
5
doSomething done
suspendDoSomething done?
0
1
2
3
4
5
suspendDoSomething done!

 

Composing suspending functions

下面我们再看一下 suspend 函数的组合调用.

 

定义两个suspend函数如下:

 

suspend fun doSomethingA(): Int {
delay(1000L) // pretend we are doing something useful here
return 10
}

suspend fun doSomethingB(): Int {
delay(1000L) // pretend we are doing something useful here, too
return 10
}


 

然后,我们调用上面的函数:

 


val d = CoroutineDemo()

val time = measureTimeMillis {
val a = d.doSomethingA()
val b = d.doSomethingB()
println("The answer is ${a + b}")
}
println("Completed in $time ms")


 

运行输出:

 

The answer is 20

Completed in 2026 ms

 

上面的方式是同步的方式. 下面我们在来看一下异步执行的方式:

 


val time = measureTimeMillis {
val a = async { d.doSomethingA() }
val b = async { d.doSomethingB() }
println("The answer is ${a.await() + b.await()}")
}
println("Completed in $time ms")

运行输出:

 

The answer is 20

Completed in 1042 ms

 

这里的 async 需要运行在一个协程环境之中,所以我们这里用了一个GlobalScope.launch。

 

async会返回一个Deferred对象,在async方法结束的时候,就会调用await()方法。因此,我们可以通过await()就可以得到异步回调。有了这个特性,我们网络请求的时候就会非常的方便。

 

 

[ref:https://kotlinlang.org/docs/reference/coroutines/composing-suspending-functions.html]

 

本文代码实例源码地址:

​https://gitee.com/universsky/kotlin-notes​

 

 

Kotlin 开发者社区

Kotlin 并发编程之"协程"_Kotlin

国内第一Kotlin 开发者社区公众号,主要分享、交流 Kotlin 编程语言、Spring Boot、Android、React.js/Node.js、函数式编程、编程思想等相关主题。

标签:协程,Kotlin,编程,kotlinx,coroutines,println,async
From: https://blog.51cto.com/u_15236724/5946918

相关文章

  • 史上最简洁Kotlin版EventBus的使用教程
    EventBus简介EventBus是一种用于Android的事件发布-订阅总线。他简化了应用程序内各个组件之间进行通信的复杂度。​​GitHub-greenrobot/EventBus:EventbusforAndroi......
  • 图书推荐:Kotlin从入门到进阶实战
    图片发自简书App《Kotlin从入门到进阶实战》从Kotlin语言的基础语法讲起,逐步深入到Kotlin进阶实战,并在最后配合项目实战案例,重点介绍了使用Kotlin+SpringBoot......
  • 2.python-练习(日期-函数式编程)
    计算活的天数"""定义函数,根据生日(年月日),计算活了多天"""fromdatetimeimportdatetimedefcalculate_alive_day(year:int,month:int,day:int)->int:......
  • c#中的AOP面向切面编程
    AOP(AspctOrientedProgramming)在不修改源代码的基础上,通过特性的方式添加一些业务逻辑。就是一些特性类在asp.netcore中通过Filter库来支持AOP的,(六种)支持一、资源缓存......
  • 5.python-函数式编程
    函数式编程(1)定义:用一系列函数解决问题。--函数可以赋值给变量,赋值后变量绑定函数。--允许将函数作为参数传入另一个函数。(2)高阶函数:将函数作为参数或返回值的函数......
  • 深度学习笔记第一门课第二周:神经网络的编程基础(下)
    本文是吴恩达老师的深度学习课程[1]笔记部分。作者:黄海广[2]主要编写人员:黄海广、林兴木(第四所有底稿,第五课第一二周,第三周前三节)、祝彦森:(第三课所有底稿)、贺志尧(第五课第......
  • Java网络编程
    Java最初是作为一种网络编程语言出现的,它能够使用网络上的各种资源和数据,与服务器建立各种传输通道,将自己的数据传送到网络的各个地方。你可以用Java很轻松地完成这些,......
  • 深入研究socket编程(1)-----socket之TCP回射服务器/客户端程序
    unix环境高级编程-------socket(套接字)中对socket编程有了初步的了解,在本篇以及后续的博客中来深入探讨各种实例以及更多的socket编程技术。         ......
  • 深入研究socket编程(5)——I/O复用的高级应用
    高级应用一:非阻塞connectconnect系统调用的man手册中有如下的一段内容:[cpp] ​​viewplain​​​​copy​​​​printEINPROGRESS  for ......
  • Python编程中的常见语句
    4.1 if条件判断语句4.1.1 if条件判断语句单分支◆单分支格式:if判断条件:语句块1……else:语句块2……Ø例:name=input('请输入您的用户名:')ifname=='admin':    ......