协程(一)——什么是协程

简介: 协程是一种全新的处理并发的设计模式,说到并发,自然就想到异步,既然是异步,那么我们就想到很多处理异步的方式,比如Rxjava,Android开发中的Handler、异步任务、service等。

协程是一种全新的处理并发的设计模式,说到并发,自然就想到异步,既然是异步,那么我们就想到很多处理异步的方式,比如Rxjava,Android开发中的Handler、异步任务、service等。

做为一个Android开发者,单开始用kotlin的时候,以为协程是kotlin才有,其实不是。

协程不是一个新的概念,而是很早之前就有,最早使用协程的编程语言可以追溯到 1967 年的 Simula 语言,在过去几年间,协程这个概念发展势头迅猛,现已经被诸多主流编程语言采用,比如 Javascript、C#、Python、Ruby 以及 Go 等。Kotlin 的协程是基于来自其他语言的既定概念。

kotlin 在1.3开始引入协程。我们主要也kotlin的协程来讲解,然后再延伸到Android上。那么既然有很多处理并发的方法了,为什么还会用协程呢?先从以下几个概念来开始了解

什么是进程
进程就是一个程序的执行实例,一个app就是一个进程

什么是线程
线程属于进程,是最小的任务执行单位,一个进程有且只有一个主线程(在Android上就是UI线程)、若干子线程。

什么是协程
java处理并发时必须切换线程,线程是最小任务执行单位,并发时必须多个线程来处理
Kotlin中的协程提供了一种全新处理并发的方式(无需切换线程),轻量级的线程,可以使用它来简化异步执行的代码,它的目的就是在保证主线程(在Android上就是UI线程)安全的基础上处理耗时任务,协程依赖于线程存在,当线程销毁了,协程也就不存在了。

协程的特点
轻量级的线程、开销小无成本、 数量几乎没有限制
容易控制生命周期
用同步的方式去表达异步
依赖于当前线程,线程结束,协程也会结束
运行在单线程中的并发处理
为什么使用协程
避免了线程间的切换、调度、数据传递导致的性能、资源浪费
协程的核心
要了解协程的核心,先从一个关键字开始,那就是spend,suspend是暂停,挂起的意思,用于修饰函数,那么被suspend修饰的函数,就是挂起函数,此函数只能在协程中或者被另外一个suspend修饰的的函数调用。

协程代码块中遇到suspend函数,会将该函数挂起执行(可以理解为当前线程中虚拟一个子线程来执行挂起函数=异步,并没有切换线程也不会阻塞当前线程),挂起函数执行完毕以后,继续执行剩余协程代码块中代码,这是协程实现异步的核心!

我们主线程(Android中指UI线程)挂起是会阻塞UI界面的,但是利用协程的核心功能,在主线程中开启一个协程去处理耗时操作,可以很好的避免阻塞问题。

很多人会问,我直接在主线程开一个新的子线程做耗时操作不也一样的吗?

答案就是,是一样,效果上是一样,但是协程做法简单,上面也说了,可以避免协程间的切换、调度,资源浪费等,因为子线程操作完耗时操作后是要切换到主线程更新UI的,而协程可以做到可以不能切换线程也可以更新UI。

而且但业务逻辑复杂的情况下,比如并发三个请求,而且是三个请求是相互关联的,这种情况下用普通的处理异步操作是很累赘很麻烦的,用协程就不一样了。这里先卖个关,下一篇文章会讲到。

依照上面协程的核心,我们看个例子:

fun test() {
    GlobalScope.launch {
        val ret= sf1()
        Log.d...... //log2 thread name
    }
    Log.d......// log3 thread name
}
suspend fun sf1():Int{
  delay(2000)
  Log.d......// log1 thread name
  //todo
}

以上代码在主线程被调用,log打印顺序是log3、log1、log2,sf1函数是可挂起函数,在协程中该函数被挂起,但并不会阻塞主线程!所以依旧先打印出了log3。
而且如果在3个log打印处打印当前线程名称,得到的结果都是是 主线程!如果你之前没有了解过协程的概念,那这将会颠覆你对异步的认知,无需切换线程也能异步!而这仅仅是刚刚开始!
通俗的表达:协程异步就是将耗时的函数标记为suspend,并在协程中调用!
以上就是针对什么是协程的一些内容,下一篇开始讲解协程的使用。

相关文章
|
JSON 数据格式
解决POSTMAN传参报错,JSON parse error: Cannot deserialize instance of `java.util.ArrayList` out of START_OB
解决POSTMAN传参报错,JSON parse error: Cannot deserialize instance of `java.util.ArrayList` out of START_OB
解决POSTMAN传参报错,JSON parse error: Cannot deserialize instance of `java.util.ArrayList` out of START_OB
|
网络协议 Linux 网络安全
Linux启动了Locust,本地浏览器访问不了WebUI页面
Linux启动了Locust,本地浏览器访问不了WebUI页面
Linux启动了Locust,本地浏览器访问不了WebUI页面
如何使用Charles进行map local
如何使用Charles进行map local
|
Linux Go vr&ar
Golang cgo:如何在Go代码中调用C语言代码?
Golang cgo:如何在Go代码中调用C语言代码?
548 0
Golang cgo:如何在Go代码中调用C语言代码?
No package 'libxml-2.0' found
No package 'libxml-2.0' found
254 0
|
存储 前端开发 JavaScript
Python3,网站搭建之编写API接口,让前端页面展示数据!
Python3,网站搭建之编写API接口,让前端页面展示数据!
558 0
Python3,网站搭建之编写API接口,让前端页面展示数据!
协程(三)—— 协程在并发中的优势
这篇文章讲讲协程在并发中的优势,并发是个复杂的过程,内部机制就不说了,不太懂也说不好,我们来讲讲处理并发的方法就行。
226 0
|
设计模式 Java 调度
协程(二)—— kotlin中协程启动的条件
这篇文章我们来讲协程的使用,简单的使用,毕竟协程是一个很强大的设计模式,深入了解需要花很多的时间,我们先从简单开始,其实学会了简单的使用,基本已经可以满足我们平时的开发需要了,话不多说,开始。
275 0
鼠标控制物体旋转、移动、缩放(Unity3D)
Unity3D对于鼠标操作物体的旋转、移动、缩放的功能点使用的比较多。 今天就分享如何使用Unity实现鼠标对于物体的旋转、移动、缩放。