问题背景

在聊天室软件源码开发中,需执行多线程任务:任务1、任务2并行执行;等全部执行完成后,执行任务3。

// 每个 任务 通过 sleep 模拟耗时
val task1: () -> String = {sleep(2000)"Hello".also { println("task1 finished: $it") }
}val task2: () -> String = {sleep(2000)"World".also { println("task2 finished: $it") }
}val task3: (String, String) -> String = { p1, p2 ->sleep(2000)"$p1 $p2".also { println("task3 finished: $it") }
}

实现方式

聊天室软件源码的「多线程同步」。Kotlin实现多线程同步的方式主要包括:(含Java实现方式)

方式1:Thread.join
方式2:线程锁:Synchronized、ReentrantLock、CountDownLatch、CyclicBarrier
方式3:CAS
方式4:Future(CompletableFuture)
方式5:Rxjava
方式6:协程Coroutine、Flow

方式1:Thread.join()

这是聊天室软件源码开发中最简单的线程同步方式

@Test
fun test_join() {lateinit var s1: Stringlateinit var s2: Stringval t1 = Thread { s1 = task1() }val t2 = Thread { s2 = task2() }t1.start()t2.start()t1.join()t2.join()task3(s1, s2)}

方式2:线程锁

主要包括:Synchronized、ReentrantLock、CountDownLatch、CyclicBarrier

Synchronized

 @Testfun test_synchrnoized() {lateinit var s1: Stringlateinit var s2: StringThread {synchronized(Unit) {s1 = task1()}}.start()s2 = task2()synchronized(Unit) {task3(s1, s2)}}

这里需要特别注意的是:在聊天室软件源码开发中为了同步多个并行任务的结果则需要声明n个锁, 即需嵌套n个 synchronized

ReentrantLock

相对于Synchronized,ReentrantLock的使用则不会出现嵌套 synchrnoized 的问题,但在聊天室软件源码开发中仍需创建多个 lock 从而管理多个不同的线程任务。

fun test_ReentrantLock() {lateinit var s1: Stringlateinit var s2: Stringval lock = ReentrantLock()Thread {lock.lock()s1 = task1()lock.unlock()}.start()s2 = task2()lock.lock()task3(s1, s2)lock.unlock()}

这里需要额外说明的是,阻塞队列BlockingQueue内部是通过ReentrantLock实现的,所以其也能实现聊天室软件源码开发中的线程同步,但其应用场景是:生产/消费场景中的同步

fun test_blockingQueue() {lateinit var s1: Stringlateinit var s2: Stringval queue = SynchronousQueue<Unit>()Thread {s1 = task1()queue.put(Unit)}.start()s2 = task2()queue.take()task3(s1, s2)
}

CountDownLatch

JUC 中的锁大都基于 AQS 实现的,可以分为独享锁和共享锁。ReentrantLock 就是一种独享锁。相比之下,共享锁更适合本场景,不需为了聊天室软件源码开发中每个任务都创建单独的锁。

 @Testfun test_countdownlatch() {lateinit var s1: Stringlateinit var s2: Stringval cd = CountDownLatch(2)Thread() {s1 = task1()cd.countDown()}.start()Thread() {s2 = task2()cd.countDown()}.start()cd.await()task3(s1, s2)}

CyclicBarrier

原理:让聊天室软件源码开发中一组线程到达一个同步点后再一起继续运行,其中任意一个线程未达到同步点,其他已到达的线程均会被阻塞。

@Test

fun test_CyclicBarrier() {

lateinit var s1: String
lateinit var s2: String
val cb = CyclicBarrier(3)Thread {s1 = task1()cb.await()
}.start()Thread() {s2 = task1()cb.await()
}.start()cb.await()
task3(s1, s2)

}

需要特别注意的是:与 CountDownLatch 的区别在于 CountDownLatch 是一次性的,而 CyclicBarrier 可以被重置后循环利用

方式3:CAS

原理:基于 CAS 的原子类计数
聊天室软件源码开发中的应用场景:一些cpu密集型的短任务同步(因为会比较损耗资源)

fun test_cas() {lateinit var s1: Stringlateinit var s2: Stringval cas = AtomicInteger(2)Thread {s1 = task1()cas.getAndDecrement()}.start()Thread {s2 = task2()cas.getAndDecrement()}.start()while (cas.get() != 0) {}task3(s1, s2)
}

这里需要特别说明的是,看到 CAS 的无锁实现,很多人会想到 volatile:并非线程安全,因为volatile 能保证可见性,但是不能保证原子性,cnt-- 并非线程安全,需要加锁操作

fun test_Volatile() {lateinit var s1: Stringlateinit var s2: StringThread {s1 = task1()cnt--}.start()Thread {s2 = task2()cnt--}.start()while (cnt != 0) {}task3(s1, s2)
}

方式4:Future

Java 1.5 开始提供了一种可以在任务执行结束时返回结果的线程同步方式:Callable 和 Future 。即不需通过定义变量来记录结果了。

// 通过 `future.get()`,可以同步等待结果返回,写起来非常方便
fun test_future() {val future1 = FutureTask(Callable(task1))val future2 = FutureTask(Callable(task2))Executors.newCachedThreadPool().execute(future1)Executors.newCachedThreadPool().execute(future2)task3(future1.get(), future2.get())
}

这里需要特别说明的是,future.get() 虽然方便,但是会阻塞聊天室软件源码开发中线程。所以在 Java 8 中引入了 CompletableFuture :他实现了 Future 接口的同时实现了 CompletionStage 接口,即可针对多个 CompletionStage 进行逻辑组合、实现复杂的异步编程。以回调的形式避免了线程阻塞

fun test_CompletableFuture() {CompletableFuture.supplyAsync(task1).thenCombine(CompletableFuture.supplyAsync(task2)) { p1, p2 ->task3(p1, p2)}.join()
}

方式5:RxJava

RxJava 提供线程同步操作符:

1.subscribeOn 用来启动异步任务
2.zip 操作符可以组合两个 Observable 的结果

fun test_Rxjava() {Observable.zip(Observable.fromCallable(Callable(task1)).subscribeOn(Schedulers.newThread()),Observable.fromCallable(Callable(task2)).subscribeOn(Schedulers.newThread()),BiFunction(task3)).test().awaitTerminalEvent()
}

方式6协程:Coroutine、Flow

Coroutine 是 Kotlin 特有的线程同步方式(前面的方式,其实都是 Java 包本身的线程同步方式。)

fun test_coroutine() {runBlocking {val c1 = async(Dispatchers.IO) {task1()}val c2 = async(Dispatchers.IO) {task2()}task3(c1.await(), c2.await())}
}

这里需要特别介绍的是,Kotlin版的 RxJava-协程加强版Flow,使用方式类似RxJava 的操作符,如 zip:

fun test_flow() {val flow1 = flow<String> { emit(task1()) }val flow2 = flow<String> { emit(task2()) }runBlocking {flow1.zip(flow2) { t1, t2 ->task3(t1, t2)}.flowOn(Dispatchers.IO).collect()
// flowOn 使得 Task 在异步计算并发射结果。}}

以上便是“聊天室软件源码开发中,该如何实现多线程同步?”的全部内容,希望对大家有帮助。

聊天室软件源码开发中,该如何实现多线程同步?相关推荐

  1. 聊天室软件源码前端性能优化,缓存角度的相关分析

    在我们考虑提高聊天室软件源码页面渲染速度之前先来思考一个问题,一个页面的速度由什么决定?显而易见,这里主要包含两方面的影响因素. 1.资源传输时间(tcp链接时间和响应时间) 2.dom渲染时间 这两 ...

  2. 聊聊语音聊天室app源码实时音视频中的技术难点:回声消除+噪声消除

    聊聊语音聊天室app源码实时音视频中的技术难点:回声消除+噪声消除 在聊聊语音聊天室app源码各个实时音视频互动场景中,回声和噪声对于影响用户体验而言都是很大的问题.音视频正在发展成为互联网线上沟通的 ...

  3. 一对一直播软件源码开发,一对一直播怎么开发

    直播行业自2016年的"千播大战",时至今日,直播平台内容同质化现象严重,反倒是一对一直播软件如"雨后春笋"般进入了人们的视野.一对一直播软件源码开发核心业务模 ...

  4. 视频交友直播软件源码开发的必备功能讲解

    相信通过这两年行业的发展我们不难看出.视频交友直播源码拥有简单直接的变现方式,深受平台和用户的喜爱,越来越多的年轻人也热衷于视频直播. 视频交友直播软件开发,支持用户在视频过程中用文字沟通,可以互相发 ...

  5. 国际短信系统平台软件源码开发路由功能—移讯云短信系统

    国际短信系统平台软件源码开发路由功能-移讯云短信系统 客户端功能介绍 1: 发送短信模块: 自定义号码短信,通讯录短信,资源短信. 2:提交任务模块: 查询当前登录账号提交的短信 3:短信明细模块: ...

  6. 一对一直播软件源码开发,iOS视频采集的实现过程

    在一对一直播软件源码日益火热的发展形势下,音视频开发(采集.编解码.传输.播放.美颜)等技术也随之成为开发者们关注的重点,本系列文章就音视频开发过程中所运用到的技术和原理进行梳理和总结. 认识 AVC ...

  7. 直播软件源码开发,直播间内消息系统的实现

    在直播软件源码开发过程中,消息系统是非常关键的,无论是直播间内的消息还是平台内的消息,都关系着用户的使用体验,所以今天我们先用一个简单的"拉"模型搭建一个简单的直播间消息系统. 基 ...

  8. 云瞻外卖江湖外卖满天星外卖美赚外卖CPS系统小程序软件源码开发

    云瞻外卖江湖外卖满天星外卖美赚外卖CPS系统小程序软件源码开发 外卖CPS红包小程序源码分享 外卖券外卖省省外卖探探美团饿了么外卖联盟优惠券小程序系统软件开发源码 美团/饿了么外卖CPS联盟返利公众号 ...

  9. PHP匿名在线聊天室系统源码 自适应PC+WAP端

    介绍: PHP匿名在线聊天室系统源码 自适应PC+WAP端 可发语音.图片 修改数据库config\settings.php可拿去搭建专门跟客户聊天的网站 网盘下载地址: http://kekewl. ...

最新文章

  1. 高版本转低版本_Tekla高版本模型转低版本模型插件
  2. Linux安装Elasticsearch+Kibana(7.10.2)
  3. Reference, List, and Completion of javascript
  4. hbase里插入big int数据用Phoenix查看的报错问题
  5. Android 自动检测更新,自动下载apk更新版本
  6. GitHub趋势:Vue.js大有超过TensorFlow之势!
  7. 横向的二级导航菜单,在多浏览器下可用
  8. va_start(),va_end()函数应用
  9. 【Kalman】卡尔曼滤波器工作原理(Link)
  10. SQL Server字符串左匹配
  11. 基于SSM的MSDN资源发布网站
  12. 社区发现算法————总结
  13. SAP结转方法:表结法、帐结法
  14. 如何查看网站服务器的速度,如何测试网站服务器访问速度?
  15. HDU5713 K个联通块
  16. 测试用例Passed和Failed有效性问题
  17. php判断是否是全英文,php判断字符串是否全英文,纯中文,中英文组合的方法
  18. SAP总账科目增强写入客商(BAPI导入)
  19. 大连北站到大连计算机学校体育馆,大连北站到圣亚海洋世界怎么走
  20. 【性能优化】PHP - 优化手段 - 学习/实践

热门文章

  1. 即时成像相机有了新发展 收据纸上印照片
  2. 快手信息流广告怎么投放?奢侈品可以在快手推广广告吗
  3. python计算机语言论坛,自学IT吧论坛国外大神-计算机科学及 Python 编程导论-中文字幕编程语言资源天地 - www.zxit8.com...
  4. npm pm2 的安装及常用命令
  5. Ubuntu终端的输入输出
  6. 联通sgip1.2接入笔记
  7. 2021海南高考成绩电话查询,2021年海南省高考成绩查询时间高招录取名单结果查询网址页面及电话.docx...
  8. 剑指offer 29 顺时针打印矩阵(可逆时针,任一点开始)
  9. JAVA:最基础部分的学习笔记
  10. TextView字幕效果