听大佬聊聊Kotlin中把码仔玩死的:协程

来源:51CTO  责任编辑:小易  

Kotlin 是一门和Java完全兼容的编程语言. 并且比java更简洁,更安全,提供了更强大函数的编程语言. 学Kotlin没有编程基础 ,那么掌握起来稍微要多花点时间;并且学完了Kotlin的语法等,可能还得学Java的相关知识 . 找一本零基础入门Kotlin的书或者教材视频,按部就班的学, 应该也能迅速掌握.来个最简单的Hello World 来比较下, 来感受下,Kotlin的帅~Java版的HelloWorldpublic class HelloClass {public static void main(String[] args) {System.out.println("Hello World");}}Kotlin版的HelloWorldfun main(args: Array<String>)=println("Hello World")www.zgxue.com防采集请勿采集本网。

即将开播:4月29日,民生银行郭庆谈商业银行金融科技赋能的探索与实践-->

 

java中将list中的一维数组中的元素取出需要2步。第一步:获取list的迭代器,将数组从迭代器中遍历取出:第二部:对取出的数组进行遍历,取出数组中存储的元素。 java的list集合中

前言

本文讲的协程主要以kotlin为主,同时可能参考python,go,但是会尽量避免使用代码,而是尝试用通俗的语言来聊协程的发展历程,尽量保证大家都能理解。

Kotlin早已是Android开发中的热门话题了,github上越来越多的项目是用Kotlin开发。但是这门语言一直处于很尴尬的境地。一方面自己不遗余力的挖掘自己在Android开发方面的

近些年,一些编程语言的新贵Go和Kotlin纷纷引入了协程这个语言特性,使得协程这个似乎十分陌生的概念开始频繁进入大家的视野,为了便于理解,开发者们都把它当作线程的小弟来对待,即轻量级线程。可是真要细说起来,协程其实是很早就出现的一个编程概念,它的出现甚至是是早于线程的,但是就编程语言的江湖地位而言,协程是不如线程的,所以向线程低头叫爸爸不奇怪。

kotlin是那个做IDE的Jetbrains公司创造的语言,它只和intellij IDEA这个IDE有关系。只是这个IDE,会在编译的时候,把kotlin转换成JAVA代码。所以kotlin无形中,便把使用者与这个

看了我上面的介绍,大家一定很纳闷,你说协程出现早,有资历,那为啥几十年的编程语言发展下来就就混成了这副咸鱼样?线程出现晚,但怎么就一棵星星之火点着了编程语言的草原。成为了编程语言中的重要概念呢??再者,协程几十年的咸鱼一条,到如今怎么突然有了梦想,翻身把歌唱的呢?

这符合我个人的经验,下面就让我开始介绍吧: Kotlin 被编译成 JVM 字节码或者 JavaScr 假如 Java 中有某些让你觉得困扰的问题,我相信 Kotlin 一定已经把它处理好了。 现在就

今天就和大家一起来梳理一下协程的整个发展历程,希望能帮助大家更加理解协程。

新建一个Android项目。 修改Gradle代码来添加Kotlin Gradle插件与标准库。 在IntelliJ或Android Studio中添加Kotlin插件。 将Kotlin类文件转换成java。

协程的出现

至于Kotlin/Native嘛。我感觉这恐怕是Jetsbrains的Kotlin宏伟计划中的重要部分了,Kotl ,未来是什么样就不知道嘞…… 最后还是想说,各个语言其实都是术业有专攻的啦。把任

咱们先来说说协程的历史,以及它是怎么混的这么惨的,毕竟悲催的人生都需要一个解释。

groovy想和python类似运行在JVM上,好多ERP用于二次开发。 Clojure,函数式编程,简单的好懂,难的函数式编程和数学书差不多。 Kotlin,可编译成Java字节码,也可以编译成Jav

协程最早诞生于1958年,被应用于汇编语言中(距今已有60多年了),对它的完整定义发表于1963 年,协程是一种通过代码执行的恢复与暂停来实现协作式的多任务的程序组件。

in out 是用来规定实现类的类型的是否可以协变。 需要写在接口或抽象方法的定义上而不是实现上。

而与此同时,线程的出现则要晚一些,伴随着操作系统的出现,线程大概在1967年被提出。线程作为由操作系统调度最小执行组件,主要用于实现抢占式的多任务。

有两个作用,一个是返回方法指定类型的值(这个值总是确定的),一个是结束方法的执行(仅仅一个return语句)。 return语句用在非void返回值类型的方法中,不但能返回基本类型,还

既然大家都搞多任务,按说谁也不能比谁强多少啊,况且协程还早生几年,理论上通过自身努力发展,在编程语言中占据核心地位是极有可能的。

app的构建依赖于androidsdk和gradle构建工具,所以,android开发相应的环境必须有的。官方推荐android6.0,sdkbuildtools使用23以上,安装app的手机系统要在5.1以上。记得安

但是这协程的发展啊,一方面当然要靠自我奋斗,另一方面,也要考虑历史进程。而上个世纪七八九十年代,是计算机疯狂朝着小型化和个人化的方向演进的时代,计算机非常依赖操作系统来提供用户交互和压榨CPU的最大性能,而操作系统怎么来压榨计算机性能的呢?靠多线程。操作系统跟随个人计算机的普及之后,编程语言自然也开始依赖操作系统提供的接口来驾驭计算机了,线程成了几乎所有编程语言跳不过的一个重要概念,并一直延续至今。

main方法呀package com.yiifox.kt.demo //文件名随意,不需要class Xxx{} fun main(args: Array<String>) { }

到这里你可能要问了,大家都是搞多任务的,为什么线程能提升cpu的资源利用率,协程不能呢?

My name is ${d.name} , and my age is ${d.age}") } kotlin简介:Kotlin 是一个基于 JVM 的新的编程语言,由 JetBrains 开发。Kotlin可以编译成Java字节码,也可以

当然有很多其他的原因能解释,但最本质的原因仍然是协程和线程是有显著区别的两个概念,到这里我们就要回过头来聊聊什么叫协作式多任务,什么叫抢占式多任务?以及这两种任务是否是同一种概念? 协作式多任务:

上图是一个寿司生产的部分工序,我们可以把图中的传送转盘和机器抓手可视作两个任务,一起协作完成了食物的生产。这就是协作式多任务。协作式的多任务要求任务之间相互熟悉,才能实现协作。 抢占式多任务:

喂金鱼的场景,一把饲料下去,所有金鱼马上围上来一抢而空,这里每个金鱼都相当于一个任务线程,这就是抢占式多任务。而抢占式多任务(线程)之间不需要了解和配合,只有竞争关系。

上面两张图,比较生动的展示了协作式多任务(协程)和抢占式多任务(多线程)之间的区别。我们能够发现,协程更加适合那些相互熟悉的任务组件通过密切配合协作完成某些工作,协作式多任务里的“任务”是一种子程序(可称为函数)。抢占式多任务里的任务则是指能抢占资源的组件或代码(其实就是线程),这里的多任务也就是多线程。所以说,协程和线程本来是差异非常大的两种概念,他们的能力是不同的,而线程的这种能力正好迎合了那个时代的需求。自我奋斗+历史进程是线程成功的主要原因。

当然,在另一方面,也由于协程是基于编程语言层面的一种概念,它并没有统一定义的接口,因此在不同的语言中实现后的效果是不同的,这也会对开发者造成极大的困扰,不利于它的推广。而反观线程,通过操作系统的统一接口,定义了大体相同的线程使用方式,保证了不同的编程语言都对线程的使用是大体一致。

讲到这里,我们来总结下协程早期发展不顺的原因:

    协程没有代表先进生产力的发展要求,先进文化的前进方向,和最广大开发者的根本利益[手动狗头]。 协程在不同编程语言中,它的实际表现有差异,非常不利于开发者的理解和使用。

以上两点,就是协程几十年以来一直不温不火的原因。我们也看到,虽然看起来都在搞多任务,但是协程和线程实际是没有太多交集的。

咸鱼翻身

虽说协程这种协作式多任务的组件不能提高程序执行的效率,似乎没有太广泛的应用前景,但这协程呐,也不能随意否定自己,因为不知道什么时候,你就突然被历史进程给关照了。

还是从线程说起,虽然线程成为编程世界的重要概念,但是在多年的使用过程中开发者们也逐渐意识到了它的痛点: 线程之间(异步代码)难以交互难度比较大,往往只能用callback,大量的callback会代码难以阅读和理解,最终让项目变得难以维护。

简单说就是在开发者端,线程之间如何更方便的交互。

而这里协程能做什么呢?

或许我再重新表达一下线程的痛点:在开发者端,线程之间如何更方便的协作。

回想一下,我们是怎么介绍协程的?协作式多任务对吧,还记得上图中的转盘和机器抓手的协作么?我们当时说这两个任务更像是两个函数的协作,但如果把转盘和机器抓手视作两个线程呢?借助编译器,把线程封装成一个个能暂停和恢复的函数,线程是不是就可以像协程设计的那样协作呢?

我们还是从代码层面来看看如今协程是如何被使用的吧。设计一个简单的需求:社区内用户进行发帖时,需要先从后台验证发帖权限,请求两个接口,那么可能我们需要尝试开启两个线程先后来完成。 普通的callback代码:

    fun tryPost(){     // 先通过接口验证权限 (实际开启了一个线程,然后等待回调)     findUserPermission(user,callback()){         public void onSuccess(UserPermission response){             // 回调 如果成功 ,检查是否有权限             if(response.hasPermission){             // 如果有权限,则访问发帖接口 (同样开启线程,等待回调)                 postContent(content,callback()){                     public void onSuccess(Result response){                         // handle successful response                     }                     public void onFail(){                                              }                 }             }else                // 如果无权限,则......             }         }                  public void onFail(){          }     } 

这是比较常见的做法,我们需要访问两次接口,而交互只能在callback中进行,但是其实代码已经很难看了,如果还有其他的逻辑的话,那代码只会更加冗杂,难以维护。

那协程是怎么解决这种痛点的呢?我们看看(kotlin和python)协程的代码如何实现这种需求: kotlin的协程代码

    // 函数通过suspend关键字标识,可以被协程调用,具备暂停恢复的能力 ,实际上仍然使用了io线程来完成接口请求 suspend fun tryfindUserPermission():PermissionResponse {     return withContext(Dispatchers.IO){         findUserPermission(user    } }  // 函数通过suspend关键字标识,可以被协程调用 suspend fun post():Result {     return  withContext(Dispatchers.IO) {         postContent(content)     } }      fun tryPost(){     //启动一个协程      launch{      //代码执行到这一行,让出cpu,进入暂停状态,等待请求成功之后,会恢复执行)      var response = tryfindUserPermission()    // 向后端访问用户权限      if(response.hasPermission){      // 有权限则开始发帖 (开启线程,让出cpu,暂停执行,等待恢复)         var response =  post()          // handle response if need     }   } 

可以看到,在kotlin中,协程通过把线程里的代码封装成一种能暂停/恢复的函数,让多线程之间的交互就像普通的函数一样简单,不需要callback。 python的协程代码

    import asyncio // async 的关键字,表明这个函数可以被协程调用 async def findUserPermission():     // handle http request     ...     ...     return response async def postContent():     // handle http request     ...     ...     return response      async def main(): // 尝试获取权限信息 同样会让出cpu,进入暂停状态,等待恢复     reponse = await findUserPermission()     // 判断有权限的情况下,进行发帖     if response.hasPermission :         res = await postContent()         // handle response if need asyncio.run(main()) 

python通过协程处理这种问题本质和kotlin是一致的。

相信大家也能看到,协程在不同的语言中的表现方式是有差异的

通过上面几段伪代码,我们能够比较清楚看到,协程能非常明显的简化了线程之间协作复杂度,让我们可以以编写同步代码的方式来编写异步代码,极大的简化你的逻辑,让你的代码容易维护。

那么协程是如何做到的呢?

虽然不同的语言中,协程有所差异,但是原理都差不多,编程语言的编译器通过一些关键字(kotlin中用suspend,python中用async等)来修饰函数,在编译期间根据关键字生成一些线程相关的代码来实现函数的暂停恢复的功能,从而实现把线程相关的代码留在编译期间产生,在开发层面就能提供像普通函数一般的协作方式。

因为解决了这个痛点,协程开始变得越来越受开发者欢迎。而协程通过编译器的帮助把线程相关的代码留在了编译期间产生,开发者可以通过操作协程就可以达到使用线程的目的,所以现在大家认为协程是一种轻量级的线程。

对于多线程的协作,或者说异步代码之间的协作并不是只有协程一家解决方案,在JS中,有promise,Java中有RxJava等等,他们都致力于解决异步编程的相关问题,希望能以编写同步代码的方式来写异步代码,目前来看,他们都做的很不错。

总结

大家对于协程的理解有很多分歧,但是对我而言,协程其实得分两个阶段来理解: 在协程诞生之初,只是用来解决编程中的某些特殊问题的编程组件,它的多任务更像多个函数的组合协作执行,那个时候,协程其实更像是一种具备暂停恢复的函数。但是这种功能似乎并不受欢迎,因此协程在很长一段时间内都是比较小众的。(此时协程和线程关系并不大) 如今它成为底层支持多线程的协作式多任务组件,很好的解决了线程协作的痛点,同时也逐渐变得越来越受欢迎,协程和线程的关系更加亲密,它们似乎也变得更加相似。(如今你可以把协程视作一种轻量级线程)

而协程的发展历程,其实也就是经历了这两个阶段。

只是你语言学的少吧,和java比是有点奇怪,但是像kotlin这种语法的还有很多,例如as3,js内容来自www.zgxue.com请勿采集。


  • 本文相关:
  • 即将开播:4月29日,民生银行郭庆谈商业银行金融科技赋能的探索与实践
  • 2020 年编程语言盘点展望:Java 老兵不死,Kotlin 蓄势待发
  • 如何避免将微服务变成分布式意大利面条式代码?
  • Google:手机厂商们请不要再自行修改 Linux 内核代码了
  • 为什么给Java代码加个空行,class文件就翻脸不认人了?
  • 独家下载!阿里如何用 AI 写代码?
  • 扛住100亿次红包请求的架构是这样设计的!
  • Java 14发布了,不使用"class"也能定义类了?还顺手要干掉Lombok!
  • 一文看懂8个常用Python库从安装到应用
  • 从一无所知到3分钟快速了解“知识图谱”
  • 十五种加速设计开发的CSS框架
  • 如何成为一个值得追随的技术管理者
  • 未来即将“触脸可及”,人脸识别技术大揭秘!
  • 关于智能运维的探索与实践
  • 你所不了解的移动支付背后的技术支撑
  • Kotlin 语法
  • 编程零基础应该怎么学 kotlin
  • 为什么我们要尝试Kotlin
  • 用kotlin写的同一个jar程序,在windows上正常运行,放到linux上就...
  • kotlin 声明了一个空数组 如何在空数组加数据
  • 如何看待 Kotlin 成为 Android 官方支持开发语言
  • kotlin可以编译成c代码吗
  • 为什么 Kotlin 是我下一门要使用的语言
  • 如何把Kotlin代码转换成java代码
  • 对比Go 语言,Kotlin 有什么优势和劣势
  • Scala,Groovy,Clojure Kotlin 分别解决了Java 的什么痛点
  • Kotlin的in out关键字
  • kotlin 函数可以多返回值么
  • Android转React Native 或者 python 好还是坚持安卓开始学Kotlin
  • 如何用kotlin创建一个app的入口
  • kotlin中怎么给list添加元素?
  • eclipse安装kotlin插件不显示
  • 免责声明 - 关于我们 - 联系我们 - 广告联系 - 友情链接 - 帮助中心 - 频道导航
    Copyright © 2017 www.zgxue.com All Rights Reserved