Android Kotlin(六)协程的并发问题

书接上回:Android Kotlin知识汇总(三)Kotlin 协程 

协程的并发问题

在一个协程中,循环创建10个子协程且单独运行各自Default线程中,并让每个子协程对变量 i 进行1000次自增操作。示例如下:

fun main() = runBlocking {var i = 0repeat(10) {val job = launch(Dispatchers.Default) {repeat(1000) {i++}}}    println("i: $i")
}
/*
输出信息:i: 9310*/

此时,这10个协程运行在不同的线程中,可能会出现并发问题,最终结果小于、等于10000。


解决并发问题 

我们知道,在 Java 中最简单的同步方式是 synchronized、Atomic、Lock等同步手段。事实上,在Kotlin 协程中也是可以同样适用这些同步手段的。

Kotlin特性之一:与 Java 的互操作性。由于 Kotlin 代码可编译为 JVM 字节码,意味着 Kotlin 利用现有的 Java 库直接调用。


Synchronized

使用 @Synchronized 注解修饰函数或 synchronized(){} 

​fun main() = runBlocking {var i = 0@Synchronizedfun add() {i++}repeat(10) {val job = launch(Dispatchers.Default) {repeat(1000) {add()}}}    println("i: $i")
}
//输出信息:i: 10000
synchronized 问题

虽然 Kotlin 协程是基于 Java 线程的,但是它已经脱离了 Java 原本的范畴。

如果在 synchronized(){} 中调用suspend挂起函数,编译器会报错。

挂起函数会被翻译为 Continuation 的异步函数,造成 synchronized 代码块无法处理同步。

  suspend fun add() {i++}

Mutex 同步锁

因为是Java 的锁是阻塞式的,会影响协程的非阻塞式特性,所以在 Kotlin 协程中,不推荐使用 Java 中的同步锁。

Kotlin 官方提供了非阻塞式的锁:Mutex。

public interface Mutex {public val isLocked: Booleanpublic suspend fun lock(owner: Any? = null)public fun unlock(owner: Any? = null)
}

Mutex 是一个接口,lock() 方法是一个挂起函数,支持挂起和恢复,这是一个非阻塞式同步锁。

为了简化try、catch、lock、unlock的模板代码,Mutex提供了withLock{} 扩展函数

public suspend inline fun <T> Mutex.withLock(owner: Any? = null, action: () -> T): T {lock(owner)try {return action()} finally {unlock(owner)}
}

使用示例如下:

fun main() = runBlocking {val mutex = Mutex()var i = 0repeat(10) {val job = launch(Dispatchers.Default) {repeat(1000) {//模板代码try {mutex.lock()i++} catch (e: Exception) {println(e)} finally {mutex.unlock()}//简化代码mutex.withLock {i++}}}}println("i: $i")
}
//输出信息:i: 10000

另外还有Actor 并发同步方式,本质是 Channel管道消息的简单封装。在 actor{} 外部,发送了10000次 AddMsg 消息,最后发送一次 ResultMsg,获取计算结果。

 

 

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

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

相关文章

Golang基础知识(笔记迁移)

golang 变量作用域 局部作用域&#xff1a;代码块、函数内的全局作用域&#xff1a;顶层作用域&#xff0c;代码块外的就是全局&#xff0c;如果变量名大写&#xff0c;则改变量整个程序都可以使用。 类型断言 golang的类型断言在变量后加上.(type)&#xff0c;如果类型断言…

69、FIFO缓存发送数据(先入先出)

本文件用于设备数据收发缓冲使用&#xff0c;本fifo采用申请2片内存区&#xff0c;交替使用&#xff0c;写0时1读,写1时0读&#xff0c;避免同时使用相同内存块 fifo区域采用头尾相连的方式循环覆盖&#xff0c;分别记录读和写的位置&#xff0c;相等则数据为空&#xff0c;否则…

脚本实现Ubuntu设置屏幕无人操作,自动黑屏

使用 xrandr 命令可以实现对屏幕的控制&#xff0c;包括调整分辨率、旋转屏幕以及关闭屏幕等。要实现 Ubuntu 设置屏幕在无人操作一段时间后自动黑屏&#xff0c;非待机&#xff0c;并黑屏后点击触摸屏可以唤醒屏幕&#xff0c;可以借助 xrandr 命令来实现。 首先&#xff0c;…

亚远景科技-ASPICE如何适配汽车电子电气产品特征与行业发展

随着当今汽车工业的蜕变&#xff0c;我们正迎来一个被誉为“软件定义汽车”的新时代。在这个时代&#xff0c;软件不仅是汽车的灵魂&#xff0c;更是其主导力量&#xff0c;它通过无形的代码赋予汽车各种突破性的特性与功能。昔日以硬件为重心的汽车行业&#xff0c;如今正在加…

计算机二级真题讲解每日一题:《format格式化》

描述 在右侧答题模板中修改代码&#xff0c;删除代码中的横线&#xff0c;填写代码&#xff0c;完成如下功能。 接收用户输入的一个小于 20的正整数&#xff0c;在屏幕上逐行递增显示从 01 到该正整数&#xff0c;数字显示的宽度为 2&#xff0c;不足位置补 0&#xff0c;后面追…

比一比gitee、gitlab、github

gitee、gitlab、github&#xff0c;哪个是目前国内大型公司使用最多的呢&#xff1f;共同点&#xff1a;三者都是基于git的代码托管工具&#xff0c;都支持版本管理。 gitee&#xff1a;适合国内开发者&#xff0c;更友好的本地化服务&#xff0c;形成了一个适合中国宝宝学习的…

计算机网络:分层体系结构

计算机网络&#xff1a;分层体系结构 基本分层概述各层次的任务物理层数据链路层网络层运输层应用层 数据传递过程分层体系常见概念实体协议服务 基本分层概述 为了使不同体系结构的计算机网络都能互联&#xff0c;国际标准化组织于 1977 年成立了专门机构研究该问题。不久他们…

算法体系-15 第十五节:贪心算法(下)

一 、贪心算法的解题套路实战 贪心的算法和排序和堆有关 1.1 描述 一些项目要占用一个会议室宣讲&#xff0c;会议室不能同时容纳两个项目的宣讲。 给你每一个项目开始的时间和结束的时间 你来安排宣讲的日程&#xff0c;要求会议室进行的宣讲的场次最多。 返回最多的宣讲场次…

centos docker 安装es

在CentOS上通过Docker安装Elasticsearch的步骤如下&#xff1a; 步骤1&#xff1a;安装Docker 在 CentOS 上安装 Docker 的步骤大致如下&#xff1a; 第一步&#xff1a;准备工作 确保你的 CentOS 系统已经更新到了最新状态&#xff1a; sudo yum update -y第二步&#xf…

【C++】1597. 买文具

问题&#xff1a;1597. 买文具 类型&#xff1a;基本运算、整数运算 题目描述&#xff1a; 花花去文具店买了 1 支笔和 1块橡皮&#xff0c;已知笔 x 元/ 支&#xff0c;橡皮 y元 / 块&#xff0c;花花付给了老板 n 元&#xff0c;请问老板应该找给花花多少钱&#xff1f; 输…

以前端角度来看序列化

1. what? why? 序列化&#xff1a;将数据结构或对象状态 转换成一个可以存储或传输的格式 的过程 意味着可以将复杂的数据结构转换成简单的字节流或字符串&#xff0c;以便于存储或传输 反序列化&#xff1a;将这些数据恢复成原始形式的过程&#xff0c;是序列化的逆过程 从…

pycharm安装插件

pycharm安装插件显示网络错误/无法安装 输入以下网址 https://plugins.jetbrains.com/ 然后重启pycharm就可以安装软件了

Spring Cloud Alibaba Sentinel 使用详解

一、Sentinel 介绍 随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。 Sentinel 以流量为切入点&#xff0c;从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 Sentinel 具有以下特征: 丰富的应用场景&#xff1a; Sentinel 承接了阿里巴…

现代游戏引擎架构

一、并行编程 1.1 为什么需要并行编程 游戏的渲染计算对算力要求很高&#xff0c;所以我们需要把操作系统的资源利用到极致。 但是摩尔定律已经不在适用了&#xff0c;硬件的发展目前已经达到瓶颈。所以我们需要通过数量来提高计算效率。 1.2 并行编程基础 进程与线程&#…

MacOS - GCC 版本升级解决方案

Mac 中自带的 GCC 版本是 4.2.1&#xff0c;由于版本太低&#xff0c;在很多操作的时候会报错。因此需要对其进行升级&#xff0c;这里使用 Homebrew 来下载最新的 GCC。 安装 Homebrew MacOS 的终端中输入如下的命令来安装 Homebrew $ /usr/bin/ruby -e "$(curl -fsSL …

sqlite3 交叉编译

#1.下载源码并解压 源码路径如下&#xff0c;下载autoconf版本 SQLite Download Page 解压 tar -zxvf sqlite-autoconf-3450200.tar.gz cd sqlite-autoconf-3450200 mkdir build # 2. 配置源代码 # 假设你已经安装了交叉编译工具链&#xff0c;如gcc-arm-linux-gnueabih…

Tkinter 一文读懂

Tkinter 简介 Tkinter&#xff08;即 tk interface&#xff0c;简称“Tk”&#xff09;本质上是对 Tcl/Tk 软件包的 Python 接口封装&#xff0c;它是 Python 官方推荐的 GUI 工具包&#xff0c;属于 Python 自带的标准库模块&#xff0c;当您安装好 Python 后&#xff0c;就可…

基于python+vue的BBS论坛系统flask-django-nodejs-php

本系统为用户而设计制作BBS论坛系统&#xff0c;旨在实现BBS论坛智能化、现代化管理。本BBS论坛自动化系统的开发和研制的最终目的是将BBS论坛的运作模式从手工记录数据转变为网络信息查询管理&#xff0c;从而为现代管理人员的使用提供更多的便利和条件。使BBS论坛系统数字化、…

关于短群签名论文阅读

参考文献为2004年发表的Short Group Signatures 什么群签名&#xff1f; 群签名大致就是由一组用户组成一个群&#xff0c;其中用户对某条消息的签名&#xff0c;改签名不会揭示是哪一个用户签署的&#xff0c;签名只能表明该消息确实是来自该群的签名。对于群还有一个群管理者…

Spring Boot 3 极速搭建OAuth2认证框架

本篇环境 Java 17Spring Boot 3.2.3Spring Authorization Server 1.2.3开发工具 SpringToolSuite4Spring Boot 3.2.3 需要JDK 17及之上的版本。 项目初始化 项目可以使用Spring的初始化器生成, 也可以创建一个Maven类型的项目。 项目创建后的目录结构如下: 项目配置 使用 …