协程是对函数和线程进一步优化的产物, 是一种函数的编排方式, 将传统意义上的函数拆成更小粒度的过程. 简单说, 就是比函数粒度还要小的可手动控制的过程.

协程可以通过yield 来调用其它协程,接下来的每次协程被调用时,从协程上次yield返回的位置接着执行,通过yield方式转移执行权的协程之间不是调用者与被调用者的关系,而是彼此对称、平等的。

协程vs函数

函数可以调用其他函数,调用者等待被调用者结束后继续执行,因此函数的生命期遵循后进先出,即最后一个被调用的函数最先结束返回。协程的生命期完全由对它们的使用需要来决定。
函数的起始处是惟一的入口点,每当函数被调用时,执行都从被调用函数的起始处开始。协程可以有多个入口点,协程的起始处是第一个入口点,每个yield返回出口点都是再次被调用执行时的入口点。
函数只在结束时一次性的返回全部结果值。协程可以在yield时不调用其他协程,而是每次返回一部分的结果值,这种协程常称为生成器或迭代器。
现代的指令集架构通常提供对调用栈的指令支持,便于实现可递归调用的函数。在以Scheme为代表的提供续体的语言环境下,可用此控制状态抽象表示来实现协程。

函数可以看作是特定状况的协程,任何函数都可转写为不调用yield的协程

协程vs线程

协程占用内存小, 在Quasar库实现中, 一个空闲的Fiber只占400个字节左右的内存, 而一个Java线程需要至少1MB, 是协程的千倍. Fibers provide functionality similar to threads, and a similar API, but they’re not managed by the OS. They are lightweight in terms of RAM (an idle fiber occupies ~400 bytes of RAM) and put a far lesser burden on the CPU when task-switching. You can have millions of fibers in an application

另外的好处是对比使用多线程来解决IO阻塞任务,使用协程不用加锁,访问共享的数据不用进行同步操作。使用协程之所以不需要加锁不是因为所有的协程只在一个线程中运行,而是因为协程的非抢占式的特点。也就是说,协程在没主动交出CPU之前都是不会被突然切换到其它协程上。而线程是抢占式的,使用多线程你不能确定线程什么时候被操作系统调度,什么时候被切换,因此需要用锁到实现一种“原子操作”的语义。

协程vs异步回调

常见的做法是使用非阻塞的IO(比如是异步IO,又或者是在syscall上自己实现的一套异步IO,如asio)并且将处理操作写在回调函数中。这样的做法一般没什么问题,但当回调函数变多,一段连贯的业务代码就会被拆分到多个回调函数之中,增加维护的成本。因此使用协程可以用同步的写法写出效果相当于是异步的代码。

在Java中通过Quasar库实现协程

对应JDK8的最高版本为0.7.9, 需要在maven中引入依赖

<dependency>
<groupId>co.paralleluniverse</groupId>
<artifactId>quasar-core</artifactId>
<version>0.7.9</version>
<classifier>jdk8</classifier>
</dependency>

通过一个channel, 将生成的数据推送给处理者, 这个流程是可以多级串联的, 达到生成和处理交叉进行的效果.

import co.paralleluniverse.fibers.Fiber;
import co.paralleluniverse.fibers.SuspendExecution;
import co.paralleluniverse.strands.channels.Channel;
import co.paralleluniverse.strands.channels.Channels; import java.util.concurrent.ExecutionException; public class FiberExample {
private static void printer(Channel<Integer> in) throws SuspendExecution, InterruptedException {
Integer v;
while ((v = in.receive()) != null) {
System.out.println("<< " + v);
}
} public static void main(String[] args) throws ExecutionException, InterruptedException, SuspendExecution {
//定义两个Channel
Channel<Integer> naturals = Channels.newChannel(1024, Channels.OverflowPolicy.BLOCK, true, true);
Channel<Integer> squares = Channels.newChannel(1024, Channels.OverflowPolicy.BLOCK, true, true); //运行两个Fiber实现.
new Fiber<>(() -> {
for (int i = 0; i < 1000; i++) {
System.out.println(">> " + i);
naturals.send(i);
}
naturals.close();
}).start(); new Fiber<>(() -> {
while (!naturals.isClosed()) {
Integer v = naturals.receive();
System.out.println("< " + v);
squares.send(v * v);
}
System.out.println("Stopped receiving messages");
squares.close();
}).start(); System.out.println("Reached printer");
printer(squares);
}
}

在Fiber的处理方法中做Thread相关的操作会引起fiber失效.

Java的协程Quasar的更多相关文章

  1. Java之协程(quasar)

    一.前面我们简单的说了一下,Python中的协程原理.这里补充Java的协程实现过程.有需要可以查看python之协程. 二.Java协程,其实做Java这么久我也没有怎么听过Java协程的东西,但是 ...

  2. 异步时代-java的协程路在何方

    面试官:你知道协程吗? 你:订机票的那个吗,我常用. 面试官:行,你先回去吧,到时候电话联系 ........ 很尴尬,但是事实是,很大一部分的程序员不知道协程是啥玩意,更大一部分的程序员,项目中没用 ...

  3. 第二章 - Java与协程

    Java与协程 内核线程的局限 通过一个具体场景来解释目前Java线程面临的困境.今天对Web应用的服务要求,不论是在请求数量上还是在复杂度上,与十多年前相比已不可同日而语,这一方面是源于业务量的增长 ...

  4. Java协程实践指南(一)

    一. 协程产生的背景 说起协程,大多数人的第一印象可能就是GoLang,这也是Go语言非常吸引人的地方之一,它内建的并发支持.Go语言并发体系的理论是C.A.R Hoare在1978年提出的CSP(C ...

  5. 协程,纤程(Fiber),或者绿色线程(GreenThread)

    纤程(Fiber),或者绿色线程(GreenThread) 面试官:你知道协程吗? 你:订机票的那个吗,我常用. 面试官:行,你先回去吧,到时候电话联系 ........ 很尴尬,但是事实是,很大一部 ...

  6. JAVA协程 纤程 与Quasar 框架

    ava使用的是系统级线程,也就是说,每次调用new Thread(....).run(),都会在系统层面建立一个新的线程,然鹅新建线程的开销是很大的(每个线程默认情况下会占用1MB的内存空间,当然你愿 ...

  7. Java不支持协程?那是你不知道Quasar!

    原创:微信公众号 码农参上,欢迎分享,转载请保留出处. 在编程语言的这个圈子里,各种语言之间的对比似乎就一直就没有停过,像什么古早时期的"PHP是世界上最好的语言"就不提了,最近我 ...

  8. java 协程

    协程是比线程更轻量级的程序处理单元,也可以说是运行在线程上的线程,由自己控制 1.适用于被阻塞的,且需要大量并发的场景. 2.不适用于,大量计算的多线程,遇到此种情况,更好实用线程去解决. 虽然Jav ...

  9. 都2019年了,Java为什么还在坚持多线程不选择协程?

    都2019年了,Java为什么还在坚持多线程不选择协程? - 知乎 https://www.zhihu.com/question/332042250/answer/734051666

  10. 深入分析 Java、Kotlin、Go 的线程和协程

    前言 协程是什么 协程的好处 进程 进程是什么 进程组成 进程特征 线程 线程是什么 线程组成 任务调度 进程与线程的区别 线程的实现模型 一对一模型 多对一模型 多对多模型 线程的"并发& ...

随机推荐

  1. 例2.6 设计一个高效的算法,从顺序表L中删除所有值为x的元素,要求时间复杂度为0(n)空间复杂度为0(1)。

    1.题目 例2.6 设计一个高效的算法,从顺序表L中删除所有值为x的元素,要求时间复杂度为0(n)空间复杂度为0(1). 2.算法思想 3.代码 void DeleteX(SeqList LA, Se ...

  2. [转帖]A Quick Look at the Huawei HiSilicon Kunpeng 920 Arm Server CPU

    https://www.servethehome.com/a-quick-look-huawei-hisilicon-kunpeng-920-arm-server-cpu/     Huawei Hi ...

  3. [转帖]关系模型到 Key-Value 模型的映射

    https://cn.pingcap.com/blog/tidb-internal-2 在这我们将关系模型简单理解为 Table 和 SQL 语句,那么问题变为如何在 KV 结构上保存 Table 以 ...

  4. [转帖]AlertManager 配置邮箱告警

    http://www.mydlq.club/article/126/ 2022-12-02 13:17:00KUBERNETESPROMETHEUSALERTMANAGER 文章目录 一.邮箱告警说明 ...

  5. [转帖]docker 镜像分层原理及容器写时复制

    https://xie.infoq.cn/article/19c98e8b15ff9f610a2ee26bd 一.镜像分层与容器层 在进行docker pull 下载镜像的时候,通过下图可以看到镜像是 ...

  6. [转帖]Linux:crontab要点整理(表达式,转义,权限管理,日志)

    https://www.jianshu.com/p/fd46652f247e 摘要:Linux,crontab整理crontab的使用,包括cron表达式,设置和删除任务,权限管理,查看日志 cron ...

  7. Rsync的一个高级应用

    Rsync的一个高级应用 背景 2019年刚开始接触linux时. 有一个很恶心的场景. 很多人为了简单起见, 提交数据库的修改(数据结果和预制数据) 都不是增量处理, 都是全量提交过来. 所以会造成 ...

  8. [转帖]基于腾讯云微服务引擎(TSE) ,轻松实现云上全链路灰度发布

    https://my.oschina.net/u/4587289/blog/8570699 1.  概述 软件开发过程中,应用发布非常频繁,通常情况下,开发或运维人员会将系统里所有服务同时上线,使得所 ...

  9. zabbix 6.0 官方文档

    Choose your platform   ZABBIX VERSION 6.0 LTS 5.4 5.0 LTS 4.0 LTS OS DISTRIBUTION Red Hat Enterprise ...

  10. 记录TritonServer部署多模型到多GPU踩坑 | 京东云技术团队

    一.问题是怎么发现的 部署chatglm2和llama2到一个4*V100的GPU机器上遇到问题 config.pbtxt 中设置模型分别在指定gpu上部署实例配置不生效 如以下配置为在gpu0上部署 ...