协程(三)—— 协程在并发中的优势

简介: 这篇文章讲讲协程在并发中的优势,并发是个复杂的过程,内部机制就不说了,不太懂也说不好,我们来讲讲处理并发的方法就行。

上一篇讲了启动协程需要满足的三大条件,同时给出了启动协程的栗子,有兴趣可以去看看,链接如下:

https://developer.aliyun.com/article/999244?spm=a2c6h.13148508.setting.14.eeac4f0eDHwSBw

这篇文章讲讲协程在并发中的优势,并发是个复杂的过程,内部机制就不说了,不太懂也说不好,我们来讲讲处理并发的方法就行。

假设现在有这个一个需求,有两个接口,我们需要将两个接口请求后的结果拼接在一起打印出来。

很简单,一般想的都是这样子,先请求接口1,完成后再请求接口2,成功后将两次结果拼接起来打印即可。

我们用Rxjava举个例子:

api.request1()
   .observeOn(AndroidSchedulers.mainThread())
   .subscribe(object:SingleObserver<String>{
       override fun onSuccess(s:String){
           api.request2(s)
               .observeOn(AndroidSchedulers.mainThread())
               .subscribe(object:SingleObserver<String>{
                   override fun onSuccess(ss:String){
                       Log.e(TAG,s+ss)
                   }
 
                   override fun onSubscribe(d:Disposable){
       
                   }
 
                   override fun onError(e:Throwable){
       
                   }
            });
       }
 
       override fun onSubscribe(d:Disposable){
       
       }
 
       override fun onError(e:Throwable){
       
       }
});

上面的代码可以实现需求,但是能进行了嵌套,代码不美观,设想一下,两个接口做了一次潜套,那如果三个接口呢?四个呢?或者更多呢?代码将十分累赘可读性极差,所以采用嵌套终究不是一个办法。

还有一个问题,现在的做法使接口按照顺序进行了执行,先接口1后再接口2,那如果需要两个接口同时请求呢?不分先后顺序,该如何打印两次请求的拼接结果呢?

我们都知道,接口的请求时间是不定的,而且是在新线程中去执行的,而我们打印是在主线程的,同时请求,我们如何确保在打印的时候,两次请求是已经执行完的呢

针对这个问题,应该会有人做一个延时操作,比如延迟10秒打印,基本可以符合要求,但是做不到万无一失,如果其中某一个接口请求在10秒没执行完呢,那岂不是拿不到接口返回数据呢?所以这种方法也不妥。

还是看看协程的做法吧,先上代码

private val mScope = MainScope()
 
mScope.launch {
    val job1 = async{
        request1()
    }
 
    val job1 = async{
        request2()
    }
 
    Log.e(TAG,${job1.await()}+${job2.await()})
}
 
//请求接口1的方法
suspend fun request1():String{
 api.request1()
               .observeOn(AndroidSchedulers.mainThread())
               .subscribe(object:SingleObserver<String>{
                   override fun onSuccess(ss:String){
                       
                   }
 
                   override fun onSubscribe(d:Disposable){
       
                   }
 
                   override fun onError(e:Throwable){
       
                   }
            });
}
 
//请求接口1的方法
suspend  fun request2():String{
 api.request2()
               .observeOn(AndroidSchedulers.mainThread())
               .subscribe(object:SingleObserver<String>{
                   override fun onSuccess(ss:String){
                       
                   }
 
                   override fun onSubscribe(d:Disposable){
       
                   }
 
                   override fun onError(e:Throwable){
       
                   }
            });
}

上面代码,我们使用了关键字suspend,把request1跟request2申明为可挂起方法,然后使用launch启动一个协程,在launch里面在开启一个子协程,使用了async的方法,然后我们打印的时候在父协程里面的。

所以,Log.e在执行的时候,会去等待,等待request1跟request2请求完成后才打印。而且可以做到request1跟request2是同时进行的,并发的,我们只不过是在他们请求的时候挂起等待,等待请求结束后再打印。

是不是感觉十分的简单,协程的优势立马凸显出来了,不存在像RxJava一样的嵌套,也不用去考虑请求结束的实际,一切都内部帮我们处理好了,我们只需要按照上面代码那么写就行,然后记得在Activity\Fragment销毁的时候cancel协程就行

mScope.cancel()

还是之前文章的那句话

协程异步就是将耗时的函数标记为suspend,并在协程中调用!不需要开启新线程,不会阻塞UI。

然后还要再加上一句,用同步的方式去表达异步

例子看上去就像同步一样,但实际上是异步执行,这就是协程的魅力所在。that‘s all

相关文章
|
2月前
|
安全 Go
Golang语言goroutine协程并发安全及锁机制
这篇文章是关于Go语言中多协程操作同一数据问题、互斥锁Mutex和读写互斥锁RWMutex的详细介绍及使用案例,涵盖了如何使用这些同步原语来解决并发访问共享资源时的数据安全问题。
88 4
|
1月前
|
安全 Go 调度
探索Go语言的并发模式:协程与通道的协同作用
Go语言以其并发能力闻名于世,而协程(goroutine)和通道(channel)是实现并发的两大利器。本文将深入了解Go语言中协程的轻量级特性,探讨如何利用通道进行协程间的安全通信,并通过实际案例演示如何将这两者结合起来,构建高效且可靠的并发系统。
|
2月前
|
数据采集 消息中间件 并行计算
进程、线程与协程:并发执行的三种重要概念与应用
进程、线程与协程:并发执行的三种重要概念与应用
61 0
|
3月前
|
监控 Devops 测试技术
|
4月前
|
消息中间件 算法 Java
(十四)深入并发之线程、进程、纤程、协程、管程与死锁、活锁、锁饥饿详解
本文深入探讨了并发编程的关键概念和技术挑战。首先介绍了进程、线程、纤程、协程、管程等概念,强调了这些概念是如何随多核时代的到来而演变的,以满足高性能计算的需求。随后,文章详细解释了死锁、活锁与锁饥饿等问题,通过生动的例子帮助理解这些现象,并提供了预防和解决这些问题的方法。最后,通过一个具体的死锁示例代码展示了如何在实践中遇到并发问题,并提供了几种常用的工具和技术来诊断和解决这些问题。本文旨在为并发编程的实践者提供一个全面的理解框架,帮助他们在开发过程中更好地处理并发问题。
|
5月前
|
安全 Android开发 Kotlin
Android面试题之Kotlin协程并发问题和互斥锁
Kotlin的协程提供轻量级并发解决方案,如`kotlinx.coroutines`库。`Mutex`用于同步,确保单个协程访问共享资源。示例展示了`withLock()`、`lock()`、`unlock()`和`tryLock()`的用法,这些方法帮助在协程中实现线程安全,防止数据竞争。
77 1
|
5月前
|
监控 程序员 调度
协程实现单线程并发(入门)
协程实现单线程并发(入门)
64 1
|
6月前
|
API 调度 Android开发
打造高效Android应用:探究Kotlin协程的优势与实践
【5月更文挑战第27天】在移动开发领域,性能优化和响应速度是衡量应用质量的关键因素。随着Kotlin语言的普及,协程作为其核心特性之一,为Android开发者提供了一种全新的并发处理方式。本文深入探讨了Kotlin协程在Android应用开发中的优势,并通过实例演示如何在实际项目中有效利用协程提升应用性能和用户体验。
|
6月前
|
调度 数据库 Android开发
构建高效安卓应用:探究Kotlin协程的优势
【5月更文挑战第27天】在移动开发领域,性能优化和流畅的用户体验始终是开发者追求的核心目标。随着Kotlin语言在Android平台的广泛采用,其提供的协程功能已经成为实现异步编程和提升应用响应性的重要工具。本文将深入探讨Kotlin协程在Android开发中的应用优势,通过与传统线程和回调机制的对比,揭示协程如何简化代码结构、提高执行效率,并最终增强应用性能。我们将从协程的基本概念出发,逐步解析其在网络请求、数据库操作和UI线程中的具体实践,以期为Android开发者提供性能优化的新思路。
|
6月前
|
移动开发 Android开发 开发者
构建高效Android应用:探究Kotlin协程的优势与实践
【5月更文挑战第21天】在移动开发领域,性能优化和流畅的用户体验是至关重要的。随着Kotlin语言在Android平台的广泛采纳,其并发处理的强大工具—协程(Coroutines),已成为提升应用响应性和效率的关键因素。本文将深入分析Kotlin协程的核心原理,探讨其在Android开发中的优势,并通过实例演示如何有效利用协程来优化应用性能,打造更加流畅的用户体验。
67 4