协程是什么?
我们知道,线程在阻塞状态和可运行状态的切换,以及线程间的上下文切换都会造成性能的损耗。为了解决这些问题,引入协程coroutine
这一概念,就像在一个进程中允许存在多个线程,在一个线程中,也可以存在多个协程。
那么,使用协程究竟有什么好处呢?
首先,执行效率高。线程的切换由操作系统内核执行,消耗资源较多。而协程由程序控制,在用户态执行,不需要从用户态切换到内核态,我们也可以理解为,协程是一种进程自身来调度任务的调度模式,因此协程间的切换开销远小于线程切换。
其次,节省资源。因为协程在本质上是通过分时复用了一个单线程,因此能够节省一定的资源。
类似于线程的五种状态切换,协程间也存在状态的切换,下面这张图展示了协程调度器内部任务的流转。
综合上面这些角度来看,和原生支持协程的go比起来,java在多线程并发上还真的是不堪一击。但是,虽然在Java官方的jdk中不能直接使用协程,但是,有其他的开源框架借助动态修改字节码的方式实现了协程,就比如我们接下来要学习的Quasar。
Quasar使用
Quasar是一个开源的Java协程框架,通过利用Java instrument
技术对字节码进行修改,使方法挂起前后可以保存和恢复jvm栈帧,方法内部已执行到的字节码位置也通过增加状态机的方式记录,在下次恢复执行可直接跳转至最新位置。
Quasar项目最后更新时间为2018年,版本停留在0.8.0
,但是我在直接使用这个版本时报了一个错误:
这个错误的大意就是这个class文件是使用的高版本jdk编译的,所以你在低版本的jdk上当然无法运行了。这里major
版本号54对应的是jdk10
,而我使用的是jdk8
,无奈降级试了一下低版本,果然0.7.10
可以使用:
<dependency>
<groupId>co.paralleluniverse</groupId>
<artifactId>quasar-core</artifactId>
<version>0.7.10</version>
</dependency>
在我们做