Kotlin 使用协程编写高效的并发程序
概念:
轻量级的线程
协程允许我们在单线程模式下模拟多线程编程的效果,代码执行时的挂起与恢复完
全是由编程语言来控制的,和操作系统无关。这种特性使得高并发程序的运行效率得到了极大的提升。
依赖库:
dependencies {
...
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.1.1"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.1.1"
}
fun main() {
GlobalScope.launch {
println("codes run in coroutine scope")
}
Thread.sleep(1000)
}
借助runBlocking函数实现在协程中所有代码执行完后再结束:
fun main() {
runBlocking {
println("codes run in coroutine scope")
delay(1500)
println("codes run in coroutine scope finished")
}
}
多个协程
子协程的特点是如果外层作用域的协程结束了,该作用域下的所有子协程也会一同结束。相比而言,GlobalScope.launch函数创建的永远是顶层协程,这一点和线程比较像,因为线程也没有层级这一说,永远都是顶层的。
fun main() {
runBlocking {
launch {
println("launch1")
delay(1000)
println("launch1 finished")
}
launch {
println("launch2")
delay(1000)
println("launch2 finished")
}
}
}
suspend挂起函数关键字
suspend关键字只能将一个函数声明成挂起函数,是无法给它提供协程作用域的。
suspend fun printDot() {
println(".")
delay(1000)
}
coroutineScope挂起函数
coroutineScope函数和runBlocking函数还有点类似,它可以保证其作用域内的所
有代码和子协程在全部执行完之前,外部的协程会一直被挂起。
suspend fun printDot() = coroutineScope {
launch {
println(".")
delay(1000)
}
}
fun main() {
//协程作用域
runBlocking {
//子协程
coroutineScope {
launch {
for (i in 1..10) {
println(i)
delay(1000)
}
}
}
println("coroutineScope finished")
}
println("runBlocking finished")
}
coroutineScope和runBlocking的区别
coroutineScope函数只会阻塞当前协程,既不影响其他协程,也不影响任何线程,因此是不
会造成任何性能上的问题的。
runBlocking函数由于会挂起外部线程,如果你恰好又在主线程中当中调用它的话,那么就有可能会导致界面卡死的情况,所以不?推荐在实际项目中使用。
实际项目中协程的使用
val job = Job()
val scope = CoroutineScope(job)
scope.launch {
// 处理具体的逻辑
}
//取消协程
job.cancel()
async函数 创建协程并获取执行结果
async函数必须在协程作用域当中才能调用,它会创建一个新的子协程并返回一个Deferred对
象,如果我们想要获取async函数代码块的执行结果,只需要调用Deferred对象的await()方法即可
fun main() {
runBlocking {
val start = System.currentTimeMillis()
val deferred1 = async {
delay(1000)
5 + 5
}
val deferred2 = async {
delay(1000)
4 + 6
}
//两个async函数同时执行,执行完后调用await()获取结果
println("result is ${deferred1.await() + deferred2.await()}.")
val end = System.currentTimeMillis()
println("cost ${end - start} milliseconds.")
}
}
withContext()函数
简化版的async函数
线程参数
Dispatchers.Default:表示会使用一种默认低并发的线程策略,当你要执行的代码属于计算密集型任务时,开启过高的并发?而可能会影响任务的运行效率。
Dispatchers.IO:表示会使用一种较高并发的线程策略,当你要执行的代码大多数时间是在阻塞和等待中,比如说执行网络请求时,为了能够支持更高的并发数量。
Dispatchers.Main:不会开启子线程,而是在Android主线程中执行代码,但是这个值只能在Android项目中使用,纯Kotlin程序使用这种类型的线程参数会出现错误。
fun main() {
runBlocking {
val result = withContext(Dispatchers.Default) {
5 + 5
}
println(result)
}
}
Kotlin 使用协程编写高效的并发程序的更多相关文章
- Kotlin Coroutine(协程): 一、样例
@ 目录 前言 一.直接上例子 1.延时任务. 2.异步任务 3.并行任务: 4.定时任务: 总结 前言 你还在用 Hanlder + Message? 或者 AsyncTask? 你还在用 Rxja ...
- 【python】-- 协程介绍及基本示例、协程遇到IO操作自动切换、协程(gevent)并发爬网页
协程介绍及基本示例 协程,又称微线程,纤程.英文名Coroutine.一句话说明什么是协程:协程是一种用户态的轻量级线程. 协程拥有自己的寄存器上下文和栈.协程调度切换时,将寄存器上下文和栈保存到其他 ...
- Kotlin Coroutine(协程): 二、初识协程
@ 目录 前言 一.初识协程 1.runBlocking: 阻塞协程 2.launch: 创建协程 3.Job 4.coroutineScope 5.协程取消 6.协程超时 7.async 并行任务 ...
- 6)协程三( asyncio处理并发)
一:使用 asyncio处理并发 介绍 asyncio 包,这个包使用事件循环驱动的协程实现并发.这是 Python 中最大也是最具雄心壮志的库之一. 二:示例 1)单任务协程处理和普通任务比较 #普 ...
- Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就绪,挂起,运行) ,***协程概念,yield模拟并发(有缺陷),Greenlet模块(手动切换),Gevent(协程并发)
Python进阶----异步同步,阻塞非阻塞,线程池(进程池)的异步+回调机制实行并发, 线程队列(Queue, LifoQueue,PriorityQueue), 事件Event,线程的三个状态(就 ...
- 【ZZ】C 语言中的指针和内存泄漏 & 编写高效的C程序与C代码优化
C 语言中的指针和内存泄漏 http://www.ibm.com/developerworks/cn/aix/library/au-toughgame/ 本文讨论了几种在使用动态内存分配时可以避免的陷 ...
- Kotlin Coroutine(协程): 三、了解协程
@ 目录 前言 一.协程上下文 1.调度器 2.给协程起名 3.局部变量 二.启动模式 CoroutineStart 三.异常处理 1.异常测试 2.CoroutineExceptionHandler ...
- 【Python3爬虫】使用异步协程编写爬虫
一.基本概念 进程:进程是一个具有独立功能的程序关于某个数据集合的一次运行活动.进程是操作系统动态执行的基本单元. 线程:一个进程中包含若干线程,当然至少有一个线程,线程可以利用进程所拥有的资源.线程 ...
- Kotlin Coroutine(协程): 四、+ Retrofit
@ 目录 前言 一.准备工作 二.开始使用 1.简单使用 2.DSL 3.扩展函数 4.请求发起 总结 前言 Retrofit 从 2.6.0 版本开始, 内置了对 Kotlin Coroutines ...
- 协程+IO切换实现并发
from gevent import monkey # 以后代码中遇到IO都会自动执行greenlet的switch进行切换 monkey.patch_all() import requests im ...
随机推荐
- 【容斥、状压dp】主旋律 题解
[清华集训2014]主旋律 题解 神秘题. 题目简述 给你一个有向图 \(G=(V,E)\).求有多少 \(E\) 的子集 \(E'\) 使得新图 \(G'=(V,E')\) 是强连通图. 强连通图的 ...
- [学习笔记].Net5项目打包到Linux系统服务时遇到的坑
如果按照官方文档的步骤手动安装.Net5 会有一个坑: 在 Linux 上手动安装 .NET - .NET | Microsoft Docs 在使用systemd打包.Net5服务的时候,无法运行, ...
- Android 优雅的Activity回调代码封装
原文地址: Android 优雅的Activity回调代码封装 - Stars-One的杂货小窝 之前提到Jetpack架构组件学习(3)--Activity Results API使用 - Star ...
- Web Audio API 第1章 基础篇
Web Audio API 第1章 基础篇 我查了一下 Web Audio API 蝙蝠书居然在 2013 年就出版了 我又看了一下我的"豆瓣读书"频道内,这本书加入到" ...
- (模板)Manacher算法:线性时间求字符串内回文子串的数量
已通过leetcode647:https://leetcode-cn.com/problems/palindromic-substrings/ void get_d(vector<int> ...
- [转载]Linux根据关键词查找文件/函数/结构体命令整理
本文来自博客园,作者:Jcpeng_std,转载请注明原文链接:https://www.cnblogs.com/JCpeng/p/15077235.html 一.查找文件 使用 Linux 经常会遇到 ...
- 编译OpenWRT-for-MT7620A(带8021x验证)
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明 本文作为本人csdn blog的主站的备份.(Bl ...
- c语言之遗漏---标准C的标记化结构初始化语法
PS:要转载请注明出处,本人版权所有. PS: 这个只是基于<我自己>的理解, 如果和你的原则及想法相冲突,请谅解,勿喷. 前置说明 本文发布于 2015-12-29 19:22:14 ...
- 三维模型OBJ格式轻量化压缩在大规模场景的加载和渲染的作用分析
三维模型OBJ格式轻量化压缩在大规模场景的加载和渲染的作用分析 OBJ格式是一种常用的三维模型文件格式,它存储了三维模型的几何信息和纹理坐标等相关属性.在大规模场景中加载和渲染三维模型时,OBJ格式的 ...
- 记录--vue3中的ref,toRef,toRefs
这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 1. ref的使用 ref 接受一个原始值,返回一个具有响应式的对象,对象有一个value属性,其值就是所传递的原始值. ref是做的一个 ...