Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2020-01-14:为什么协程比线程要轻量? #233

Open
MoJieBlog opened this issue Jan 14, 2020 · 19 comments
Open

2020-01-14:为什么协程比线程要轻量? #233

MoJieBlog opened this issue Jan 14, 2020 · 19 comments
Labels

Comments

@MoJieBlog
Copy link
Collaborator

No description provided.

@byzyhm
Copy link

byzyhm commented Jan 16, 2020

一条线程可以开很多协程

@buptmaster
Copy link

协程是编译器级别的,线程和进程是os级别的。协程的顺序决定是编译器安排代码决定的,kotlin的协程方便之处在于,可以优雅的切换协程代码的线程执行环境,比以前的实现方式要方便的多。

@attiqrehman1991
Copy link

attiqrehman1991 commented Jan 27, 2020

1. Performance
Creating too many threads can actually make an application underperform in some situations; threads are objects which impose overhead during object allocation and garbage collection.

To overcome these issues, Kotlin introduced a new way of writing asynchronous, non-blocking code; the Coroutine.

Similar to threads, coroutines can run in concurrently, wait for, and communicate with each other with the difference that creating them is way cheaper than threads.

There are many other websites and statistics proving the point, that having coroutines is much cheaper than using java threads.

From my own experiences - I build an application in my company for logistics which has at some point of runtime over 20 coroutines running in parallel - I never had in 1,5 years of using them any 'OutOMemory', 'StackOverflow', or 'slowing down the main application' problems.

2. Usability / Difficulty
Compared to java Threads, using Kotlin's coroutines is very easy and doesn't enforce you to change the way you code.

Usually working in Java with Java threads, people built so many 'procedures' or classes to add safety with multi-threading, that it creates a big overhead of things to know about before you do real good multi-threading. And it takes a lot of time.

In Kotlin it's easy: you don't need Thread pools or twerking the code to make it asynchronous - you just do it with easy keyword async.

@caikaidev
Copy link

kotlin的协程,其实就是一套线程的框架,类似Java的Executor。当你不停的启动协程的时候,其实底层是维护了一个线程池的,所以会比你不停的new Thread()。要更加的轻量。

@caikaidev
Copy link

@buptmaster 喷之前看清楚?谁说了kotlin 协程 是不停的创建线程了?

@buptmaster
Copy link

算我没看清楚,所以我立即删除了,我的锅。那你告诉我,“当你不停的启动协程的时候,其实底层是维护了一个线程池的,所以会比你不停的new Thread()。要更加的轻量。”为什么维护了线程池就更轻量?

@buptmaster
Copy link

线程池在大量任务同时需要执行时,不还是不停的“new Thread()”,所以细细想来我也没说错啊

@buptmaster 喷之前看清楚?谁说了kotlin 协程 是不停的创建线程了?

@caikaidev
Copy link

@buptmaster 线程池能够重复利用已创建的线程,降低线程的创建和销毁所需资源。
你启动10次协程跟直接启动10个线程去做一些事情。那这个时候使用协程是不是比你直接使用线程轻量一点。

以上是我的理解,你有意见可以提出,不要上来就喷。

你可先去看看线程池。。那按照你这么说,要线程池干嘛。都直接每次使用的时候new Thread不就完事了。

@buptmaster
Copy link

我可能语气是有点问题,算我的。可是你的回复中,还是没解释为什么啊,你的意思是维护了一个线程池,那为何还要协程这个东西?不直接用线程池?

@caikaidev
Copy link

@buptmaster 每次new Thread() 是需要很大代价的。这个你可以理解的把。 那我用协程,不会去每次new Thread() 。这样不是更轻量。

用协程跟用线程池,我觉得性能上是一样的。(所以并不是因为性能原因,我用协程而不用线程池)

为什么要协程这个东西,协程牛逼的地方在于可以通过用编写同步代码的方式,去做异步的事情,这个才是大家推崇的原因把。

@liyanfei250
Copy link

并没有比线程轻量级,顶多就是写法非常舒服,基于线程的封装而已,自己试试就知道了

@cellzer
Copy link

cellzer commented Aug 24, 2021

我记得扔物线有出过视频专门讲过这个,线程和协程底层都是一样的东西,没有谁更优更劣,协程本质就是对线程池的封装

@lkv1988
Copy link

lkv1988 commented Nov 24, 2021

单就这个问题,我认为之所以比线程轻量的原因是其底层会根据开发者的诉求复用已有的几个线程池,而无需开发者自己去管控线程,这一点上所谓“轻量”是coding层面关心的东西更少,背后的语法糖通过编译器就帮你把任务丢到线程池中去了。

另外,总的来说协程的轻量级应该更多的是体现在可以利用语法糖把线程、回调的切换做的十分优雅。相比而言,自己去做线程之间的切换、通信,单单从代码量上来说就重了很多。性能上协程也调优了一些常用类型的线程池,不用自己再去new出来,常见的操作都可以cover住了。

@yihu5566
Copy link

yihu5566 commented Jul 8, 2022

个人认为,之所以轻量应该是对比直接操作线程来讲;
协程主要的优势应该是它的策略,任务更加合理的分配安排,
让任务在线程运行的更加高效。

@Edger
Copy link

Edger commented Jul 27, 2022

建议写清楚那个平台再来讨论这个问题

@yizems
Copy link

yizems commented Aug 1, 2022

@Edger 建议看看项目名

@yizems
Copy link

yizems commented Aug 1, 2022

我认为轻量可以从两个方面来说:

  1. 编码复杂度: kotlin 提供了优秀的编译机制, 写法上我就不多说了, 的确很简单就是了, 可以搜索kotlin 协程原理
  2. 性能消耗:
    2.1 在不考虑线程池的情况下, 我们基本上是每个任务创建一个线程,,那么这个时候协程肯定是比线程轻量的;因为协程内部是由线程池来执行的
    2.2 考虑线程池的情况:没有差异: 协程再某些情况下会因为额外的线程切换导致更多的性能消耗

再说一句: 没有kotlin 协程,没有suspend, 我们也可以实现协程的, 只不过要手写很多复杂的代码就是了

@Edger
Copy link

Edger commented Aug 1, 2022

@Edger 建议看看项目名

首先,协程并不是 Android 或 Kotlin 才有的概念

其次,Kotlin 协程在 JVM 上就不是真正的协程,并不会比线程池轻量化,而在 JS 上它就是真正的协程,比线程要轻量化

再次,我们讨论一个跨语言的概念,不是说这是一个 Android 的仓库就局限在 Android 里面。界定好范围,会更有利于清晰地比较协程在不同平台的差异。

最后,上面有一些答案就是没有区分平台场景的,可以说是错的,或者有失偏颇的,所以写清楚那个平台是有必要的。

建议理解我的建议再提建议。

@yizems
Copy link

yizems commented Aug 3, 2022

唉, 非要把问题搞的那么大么, 是不是还要搞到 有栈和无栈协程的实现上去 =.= , js 的 c++ 或者 汇编代码, go 的源码 是不是也要捞出来瞅瞅。 一天天的卷死得了

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests