Kotlin基础——异步和并发

同步和异步

  • 同步指的是一种行为:当执行IO操作的时候,在代码层面上我们需要主动去等待结果,直到结果返回
  • 阻塞指的是一种状态:当执行IO操作的时候,线程处于挂起状态,就是该线程没有执行了

故同步不是阻塞,同步也可以是非阻塞的,如在执行同步代码块时,线程可以不阻塞而是一直在后台运行

代码中一般通过和多线程和回调来实现异步非阻塞

但多线程只是看上去同时执行,底层原理是通过CPU调度来实现的,当一个线程切换到另一个线程时,通常需要

  • 保存当前线程的执行上下文
  • 载入另一个线程的执行上下文

切换线程也是需要开销的,故当线程切换很频繁时,可能会导致多线程并不优于单线程

协程Coroutine

大量回调会使代码更加复杂,且会存在多层次的回调,同时线程切换的开销不可忽略,而协程则可以避免这些问题

协程是一个无优先级的子程序调度组件,允许子程序在特定的地方挂起恢复

  • 进程包含线程,线程包含协程
  • 一个线程可以有任意多个协程
  • 某一时刻只能由一个协程在运行,多个协程分享该线程分配到的计算机资源
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-core:1.4.1"
implementation "org.jetbrains.kotlinx:kotlinx-coroutines-android:1.4.1"

使用Coroutine需要导入包,如下通过launch构造了一个协程,通过delay()挂起协程,但不会阻塞线程

GlobalScope.launch {delay(1000L)println("World")
}
println("Hello, ")
Thread.sleep(2000L)

线程是由操作系统来调度的,而协程的切换可以由程序自己来控制,协程可以创建很多个,而线程是有限的

launch和runBlocking

  • delay只能在协程内部使用,用于挂起协程,不会阻塞线程
  • sleep用来阻塞线程

未避免混淆,可以使用runBlocking创建主协程,而使用launch创建子协程,从而在内部都使用delay(),但需要注意,runBlocking依旧会阻塞当前执行的线程

fun test() = runBlocking {GlobalScope.launch {delay(1000L)println("World")}println("Hello, ")delay(2000L)
}

协程声明周期和join

当执行耗时操作,但并不知道需要多久时,为使程序一直保活,可以使用join

  • 如下程序会一直等待,直到协程结束,这里的等待是非阻塞式,不会将当前线程挂起
  • suspend修饰的方法只能在协程内部或其他suspend方法中使用
fun test() = runBlocking {val job = launch {search()}println("Hello,")job.join()
}suspend fun search() {delay(1000L)println("World")
}

用同步方式写异步代码

在下面代码中,两个方法是顺序执行的

fun test() = runBlocking<Unit> {val one = searchOne()val two = searchTwo()println("search is ${one} and ${two}")
}suspend fun searchOne() {delay(3000L)println("one")
}suspend fun searchTwo() {delay(1000L)println("two")
}

打印如下

one
two
search is kotlin.Unit and kotlin.Unit

为了让其并行执行,可以使用async和await

  • 使用async相当于创建了一个子协程,会和其他子协程一样并行工作
  • async返回Deferred,是一个非阻塞可取消的future,其是一个带有结果的job,而Launch也会返回一个job但无返回值
  • future的意思是将来会返回一个结果,利用await可以等待返回值查询到之后获取出来
fun test() = runBlocking<Unit> {val one = async { searchOne() }val two = async { searchTwo() }println("search is ${one.await()} and ${two.await()}")
}

打印如下

one
two
search is kotlin.Unit and kotlin.Unit

共享资源控制

如对于下面的数据

val goods = hashMapOf<Long, Int>()
goods.put(1, 10)
goods.put(2, 15)

Synchronized

使用@Synchronized或synchronized()实现加锁

@Synchronized
fun buyGoods(id: Long) {val stock = goods.getValue(id)goods.put(id, stock - 1)
}
fun buyGoods2(id: Long) {synchronized(this) {val stock = goods.getValue(id)goods.put(id, stock - 1)}
}

Lock

var lock: Lock = ReentrantLock()
fun buyGoods3(id: Long) {lock.lock()try {val stock = goods.getValue(id)goods.put(id, stock - 1)} catch (ex: Exception) {println(ex)} finally {lock.unlock()}
}

上面写法有以下问题:

  • 若有多个同步方法,将会竞争同一把锁
  • 加锁后可能忘记解锁
  • 重复的模板代码
fun <T> withLock(lock: Lock, action: () -> T) {lock.lock()try {action()} catch (ex: Exception) {println(ex)} finally {lock.unlock()}
}
fun buyGoods(id: Long) {val stock = goods.getValue(id)goods.put(id, stock - 1)
}
var lock: Lock = ReentrantLock()
withLock(lock, { buyGoods(1) })

上面使用高阶函数进行了优化,库函数也自带withLock()方法

fun buyGoods(id: Long) {val stock = goods.getValue(id)goods.put(id, stock - 1)
}
var lock: Lock = ReentrantLock()
lock.withLock({ buyGoods(1) })

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

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

相关文章

前端工程化08-新的包管理工具pnpm

1、历史原因解读 pnpm这个东西发布的时间是比较早的&#xff0c;但是在最近一两年的时候才开始流行&#xff0c;甚至是可以说非常的盛行&#xff0c;那么这个包到底是个什么东西的&#xff0c;那么我们先说下&#xff0c;原来的包管理工具到底有那些问题&#xff1f;比如说我们…

MySQL自增主键踩坑记录

对于MySQL的自增主键&#xff0c;本文记录、整理下在工作中实际遇到的问题。 下面示例均基于MySQL 8.0 修改列的类型后&#xff0c;自增属性消失 CREATE TABLE users (id INT AUTO_INCREMENT PRIMARY KEY,username VARCHAR(50) NOT NULL,email VARCHAR(100) NOT NULL );上面的…

论文学习——一种自适应提升的动态多目标优化进化算法

论文题目&#xff1a;A dynamic multi-objective optimization evolutionary algorithm with adaptive boosting 一种自适应提升的动态多目标优化进化算法&#xff08;Hu Peng a,b,∗, Jianpeng Xiong a, Chen Pi a, Xinyu Zhou c, Zhijian Wu d&#xff09;IEEE Swarm and Ev…

phpstorm2024代码总是提示“no usages”或者“无用法”解决办法

问题&#xff1a;phpstorm2024使用时&#xff0c;总是会提示无用法&#xff0c;如果没有安装中文语言包的情况下会提示&#xff1a;no usages&#xff0c;如果想关闭怎么办&#xff1f; 编译器右上角点击齿轮进入设置&#xff0c;按照下图的方法点击即可关闭。或者在编译器的“…

机器学习——强化学习中的“策略π”的个人思考

这两天回顾了《西瓜书》中的最后一章——“强化学习”&#xff0c;但是忽然发现之前对于本章中的“策略π”的理解有些偏差&#xff0c;导致我在看值函数公式时有些看不明白。对此&#xff0c;我在网上查了一些资料&#xff0c;但是大部分人都是一笔带过&#xff0c;或者是照本…

c++ 设计模式 的课本范例(中)

&#xff08;10&#xff09;单例模式 singleton 。整个应用程序执行时&#xff0c;只有一个单例模式的对象。 class GameConfig // 懒汉式&#xff0c;啥时候用单例对象&#xff0c;啥时候创建。 { private:static GameConfig* ptrGameConfig; // 这些函数都作为私有函数&…

Linux编译升级Python 2.7.5到Python3的版本

1.安装编译Python需要的依赖 yum install wget zlib-devel bzip2-devel openssl-devel ncurses-devel sqlite-devel readline devel tk-devel gcc make zlib zlib-devel2.下载Python3的安装包 wget https://www.python.org/ftp/python/3.12.4/Python-3.12.4.tgz3.解压编译Pyt…

Python爬虫实作篇

本次以Dcard宠物版为例 程式码撰写逻辑 先以宠物版首页将所以文章连结爬下来存到list里&#xff0c;那就会考虑到浏览器往下滑换页&#xff0c;所以要送一个GET从list将连结一个一个取出来组合成正确的网址&#xff0c;并GET下来&#xff0c;寻找图片的标签如果有图片的标签就…

RAG技术:在自然语言处理中的深度融合与创新

在自然语言处理&#xff08;NLP&#xff09;领域&#xff0c;随着技术的不断进步&#xff0c;我们见证了各种创新方法的涌现。其中&#xff0c;检索增强生成&#xff08;Retrieval-Augmented Generation&#xff0c;简称RAG&#xff09;技术以其独特的优势&#xff0c;逐渐成为…

【wsl2】WIN11借助wsl2挂载ext4磁盘

我有一块ext4文件系统的硬盘&#xff0c;想要在win11上访问&#xff0c;我们可以通过wsl2进行挂载 wsl2的安装就跳过了&#xff0c;可以自行搜索安装。 安装完成后 >>> GET-CimInstance -query "SELECT * from Win32_DiskDrive"通过这个命令&#xff0c;可…

汽车电子工程师入门系列——AUTOSAR通信服务框架(上)

我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节…

jad反编译工具笔记

文章目录 下载 反编译 其他官网地址命令参数 反编译是有些应用场景的。 方法也不只一种。 1、jad.exe实现反编译。 2、阿里arthas监控工具带。 3、idea直接打开.class文件就是反编译(是不是很方便)。 这里只说jad.exe这种。 下载 官网下载地址(这是jad158g.win版本)&#xff…

Spring Boot项目如何配置跨域

1、通过SpringSecurity进行配置 2、前端跨域配置&#xff1a;proxy配置项用于设置代理规则&#xff0c;用于前端开发中与后端API交互时使用。

ROS2自定义接口Python实现机器人移动

1.创建机器人节点接口 cd chapt3_ws/ ros2 pkg create example_interfaces_rclpy --build-type ament_python --dependencies rclpy example_ros2_interfaces --destination-directory src --node-name example_interfaces_robot_02 --maintainer-name "Joe Chen" …

Java 基本数据类型【基础篇】

目录 Java 数据类型基本数据类型整数类型【byte、short、int、long】浮点类型【float、double】布尔类型【boolean】字符类型【char】 引用数据类型 Java 数据类型 Java 语言支持的数据类型分为两种&#xff1a;基本数据类型 和 引用数据类型。其数据类型结构如下图所示&#x…

24年hvv前夕,微步也要收费了,情报共享会在今年结束么?

一个人走的很快&#xff0c;但一群人才能走的更远。吉祥同学学安全https://mp.weixin.qq.com/s?__bizMzkwNjY1Mzc0Nw&mid2247483727&idx1&sndb05d8c1115a4539716eddd9fde4e5c9&scene21#wechat_redirect这个星球&#x1f517;里面已经沉淀了&#xff1a; 《Ja…

【高考志愿】信息与通信工程

目录 一、专业介绍 1.1 专业概述 1.2 学科设置 1.3 课程设置 二、培养目标 三、就业前景 四、志愿填报建议 五、信息与通信工程专业排名 信息与通信工程是一门具有深度与广度的综合性工程学科&#xff0c;它不仅涵盖了信息的传输、处理以及通信系统设计与优化的各个方面…

SQL CASE WHEN语句的使用技巧

SQL CASE WHEN语句的使用技巧 大家好&#xff0c;我是免费搭建查券返利机器人省钱赚佣金就用微赚淘客系统3.0的小编&#xff0c;也是冬天不穿秋裤&#xff0c;天冷也要风度的程序猿&#xff01; 在SQL查询中&#xff0c;经常需要根据不同的条件进行分支处理&#xff0c;这时就…

30 哈希的应用

位图 概念 题目 给40亿个不重复的无符号整数&#xff0c;没排过序。给一个无符号整数&#xff0c;如何判断一个数是否在这40亿个整数中 1.遍历&#xff0c;时间复杂度O(N) 2.二分查找&#xff0c;需要先排序&#xff0c;排序(N*logN)&#xff0c;二分查找&#xff0c;logN。…

2024年【焊工(初级)】考试及焊工(初级)报名考试

题库来源&#xff1a;安全生产模拟考试一点通公众号小程序 焊工&#xff08;初级&#xff09;考试是安全生产模拟考试一点通生成的&#xff0c;焊工&#xff08;初级&#xff09;证模拟考试题库是根据焊工&#xff08;初级&#xff09;最新版教材汇编出焊工&#xff08;初级&a…