java为什么没有协程?协程和多线程的区别是什么?协程比多线程好?或者说协程为了解决什么问题?

来源:3-3 SimpleDateFormat线程不安全的原因

春去_秋来

2020-09-17

java为什么没有协程?协程和多线程的区别是什么?协程比多线程好?或者说协程为了解决什么问题?

写回答

2回答

张勤一

2020-09-17

春去秋来你好:

    首先来说,Java 中为什么没有协程我不清楚,不过这个也确实是不重要。毕竟,你在面试、学习、工作的过程中,如果使用的是 Java 语言,协程这个概念几乎都是可以忽略的。那么,既然这里你问到了协程,我就简单来说下协程与线程。

    协程其实可以认为是比线程更小的执行单元。为啥说他是一个执行单元,因为他自带CPU上下文。这样只要在合适的时机,我们可以把一个协程切换到另一个协程。只要这个过程中保存或恢复 CPU上下文那么程序还是可以运行的。

    协程可以理解为纯用户态的线程,其通过协作而不是抢占来进行切换。相对于进程或者线程,协程所有的操作都可以在用户态完成,创建和切换的消耗更低。总的来说,协程为协同任务提供了一种运行时抽象,这种抽象非常适合于协同多任务调度和数据流处理。在现代操作系统和编程语言中,因为用户态线程切换代价比内核态线程小,协程成为了一种轻量级的多任务模型。

    从编程角度上看,协程的思想本质上就是控制流的主动让出(yield)和恢复(resume)机制,迭代器常被用来实现协程,所以大部分的语言实现的协程中都有 yield 关键字,比如 Python、Lua。但也有特殊比如 Go 就使用的是通道来通信。我们看张图来理解下协程和线程的关系:

980882-20200426141416098-2126696932.png

    那么,线程和协程之间到底有什么不同呢?

    线程切换从系统层面远不止 保存和恢复 CPU上下文这么简单。操作系统为了程序运行的高效性每个线程都有自己缓存Cache等等数据,操作系统还会帮你做这些数据的恢复操作。所以线程的切换非常耗性能。但是协程的切换只是单纯的操作CPU的上下文,所以一秒钟切换个上百万次系统都抗的住。

    最后,协程对比线程有以下 3 个重要的优势:    

    (1)减少了线程切换的成本。线程,不管是创建还是切换,都需要较高的成本。子程序切换不是线程切换,而是由程序自身控制,因此,没有线程切换的开销,和多线程比,线程数量越多,协程的性能优势就越明显。这也就是说,协程的效率比较高

    (2)协程的第二大优势就是没有并发问题,不需要多线程的锁机制,因为只有一个线程,也不存在同时写变量冲突,在协程中控制共享资源不加锁,只需要判断状态就好了,所以执行效率比多线程高很多

    (3)协程更轻量级。创建一个线程栈大概需要 1M 左右,而协程栈大概只需要几 K 或者几十 K


    我是勤一,致力于将这门课程的问答区打造为 Java 知识体系知识库,Java 知识体系 BBS!共同建造、维护这门课程,我需要每一个你!

2
2
慕妹9162326
fiber quasar ea-async Coroutine
2021-04-03
共2条回复

春去_秋来

提问者

2020-09-17

既然协程比线程好,那java的多线程不是没啥用了,鸡肋了?

0
4
过客12
java目前引入协程来看,并没有明显的利好,反而引入会花费很高的成本。比如说java明天突然发布了协程的api,你一定会去学吗?你实际工作中一定会用到吗?都存在很多未知。。。而且首先是你要理清协程的概念,它有什么作用,引入后能解决什么问题?其实它主要是为了解决IO密集度高的多线程操作带来的频繁的上下文切换的开销。这些问题能先想想能用其他方式解决吗?答案是可以的,java提供了nio、aio这些东西都还没有完全使用起来,短时间内就没必要再引入新的协程了。最后来看,引入协程后,没有一点坏处吗?协程之间的调度由程序员来做岂不是成本更高?用现成的操作系统来调度的线程不是更香
2020-11-17
共4条回复

Java实操避坑指南 SpringBoot/MySQL/Redis错误详解

掌握业务开发中各种类型的坑,,Java web开发领域通用

466 学习 · 204 问题

查看课程