ava使用的是系统级线程,也就是说,每次调用new Thread(....).run(),都会在系统层面建立一个新的线程,然鹅新建线程的开销是很大的(每个线程默认情况下会占用1MB的内存空间,当然你愿意的话可以用-Xss来调小点),更不要说线程切换带来的开销了

为了节省开销,程序员玩出了很多花样。

最常用的是线程池(线程复用,但是完全无法处理阻塞调用的问题)

以及事件驱动框架(NIO或者Netty,用少量的工作线程来服务大量的慢速IO连接,但是EventLoop中也不能有阻塞调用,耗时的逻辑必须放在额外的线程池里处理)

但是NIO的代码难写也难懂,像我这种懒惰的程序猴子,最喜欢的还是一个线程对应一个连接这种简单粗暴的编程手法。

纤程(Coroutine)是我们的救星

所谓的纤程,或者协程,可以理解为是一种轻量级的线程,它与线程的主要区别在于

a. 线程切换的过程是由系统内核完成,切换的过程中会进入到内核态。而纤程则完全工作在用户态。

b. 线程是否发生切换是由操作系统决定的(抢占式调度),工作线程本身没有决定权。而纤程的切换是需要工作纤程主动放弃CPU,这样调度器才能让另外一个纤程继续运行。

很多语言已经内置了纤程,最著名的应该就是Go了,用go关键字,就能直接创建一个纤程并在其中为所欲为,其他的Scheduler会自动帮你搞定。所以Go能相对容易的写出正确的高并发程序。

可惜的是,Java没有官方的纤程支持,好在有个叫做Quasar的库可堪一用

使用这个lib,你就能在Java程序中创建纤程了,代码大概长这个样子:

    public static void main(String[] args)
throws ExecutionException, InterruptedException, SuspendExecution {
int FiberNumber = 1_000_000;
CountDownLatch latch = new CountDownLatch(1);
AtomicInteger counter = new AtomicInteger(0); for (int i = 0; i < FiberNumber; i++) {
new Fiber(() -> {
counter.incrementAndGet();
if (counter.get() == FiberNumber) {
System.out.println("done");
}
Strand.sleep(1000000);
}).start();
}
latch.await();
}

在上面这段代码中,我们直接创建了一百万个纤程,如果是一般的Thread,不考虑OS能否负担得起,单单占用的内存就要1T起步。

但是这段程序实际占用的内存只在1G出头,也就是说每个纤程的内存占用只在1K左右。

这是如何做到的?

Quasar在编译时会对代码进行扫描,如果方法带有Suspendable注解,或者抛出SuspendExecution,或者在配置文件中被指定,Quasar会直接修改生成的字节码,在park方法的前后,插入一些字节码。

这些字节码会记录此时纤程的执行状态(相关的局部变量与操作数栈),然后通过抛出异常的方式将CPU的控制权从当前协程交回到控制器

此时控制器可以再次调度另外一个纤程运行,并通过之前插入的那些字节码恢复当前纤程的执行状态,使程序能继续正常执行。

并且,这些操作是非常轻量的,所以内存消耗极小,也不会对CPU带来太多的额外开销(据说在3%-5%)

JAVA协程 纤程 与Quasar 框架的更多相关文章

  1. Java 中的纤程库 – Quasar

    来源:鸟窝, colobu.com/2016/07/14/Java-Fiber-Quasar/ 如有好文章投稿,请点击 → 这里了解详情 最近遇到的一个问题大概是微服务架构中经常会遇到的一个问题: 服 ...

  2. 继续了解Java的纤程库 – Quasar

    前一篇文章Java中的纤程库 – Quasar中我做了简单的介绍,现在进一步介绍这个纤程库. Quasar还没有得到广泛的应用,搜寻整个github也就pinterest/quasar-thrift这 ...

  3. 纤程与Quasar

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

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

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

  5. java 协程

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

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

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

  7. Java协程编程之Loom项目尝鲜

    前提 之前很长一段时间关注JDK协程库的开发进度,但是前一段时间比较忙很少去查看OpenJDK官网的内容.Java协程项目Loom(因为项目还在开发阶段,OpenJDK给出的官网https://ope ...

  8. 基于纤程(Fiber)实现C++异步编程库(一):原理及示例

    纤程(Fiber)和协程(coroutine)是差不多的概念,也叫做用户级线程或者轻线程之类的.Windows系统提供了一组API用户创建和使用纤程,本文中的库就是基于这组API实现的,所以无法跨平台 ...

  9. nodejs中的fiber(纤程)库详解

    fiber/纤程 在操作系统中,除了进程和线程外,还有一种较少应用的纤程(fiber,也叫协程).纤程常常拿来跟线程做对比,对于操作系统而言,它们都是较轻量级的运行态.通常认为纤程比线程更为轻量,开销 ...

随机推荐

  1. 洛谷 P816 忠诚 题解

    每日一题 day28 打卡 Analysis 这道题用线段树维护区间最小值很简单,因为没有修改所以连lazy_tag都不用,但是这道题可以用树状数组维护区间最小值,非常骚气. 线段树代码: #incl ...

  2. test命令用法。功能:检查文件和比较值

    test命令用法.功能:检查文件和比较值 1)判断表达式 if test  (表达式为真) if test !表达式为假 test 表达式1 –a 表达式2                  两个表达 ...

  3. GDB十分钟教程【转载于网络爱好者】

    本文写给主要工作在Windows操作系统下而又需要开发一些跨平台软件的程序员朋友,以及程序爱好者. GDB是一个由GNU开源组织发布的.UNIX/LINUX操作系统下的.基于命令行的.功能强大的程序调 ...

  4. leetcode解题报告(33): Find All Numbers Disappeared in an Array

    描述 Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and ...

  5. Pro自定义数据源原理

    1.  概念 Connector:定义连接到一个数据源的连接信息,用于创建datastore. Datastore:代表一个数据源的实例,用于打开一个或多个tables或feature class. ...

  6. 利用斗图啦网站API批量下载表情图片

    decorator.py #!/usr/bin/env python # -*- coding: utf-8 -*- import logging import os from functools i ...

  7. HugeGraph入门

    一.HugeGraph简介 最近在搞好友推荐方便的工作,选择了图数据的方法,使用并学习了HugeGraph,再次记录一下. HugeGraph是百度在2018年中旬开源的一款图数据库(Graph Da ...

  8. POJ1177和POJ1389 。。。

    POJ 1177 Picture 经典线段树+离散化+扫描线 POJ 1177 Picture (线段树+离散化+扫描线) 详解 线段树(segment tree) http://www.java3z ...

  9. AUC,ROC我看到的最透彻的讲解

      版权声明:本文为博主原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明. 本文链接:https://blog.csdn.net/u013385925/article/d ...

  10. ArcGIS Python人门到精通目录基于ArcGIS10.2,100以上案例15章42个视频806分钟,51GIS网站上线

    ArcGIS Python人门到精通目录 闫老师 QQ:276529800 微信13108507190 1.  ArcGIS Python基础 1.1  ArcGIS为什么学习Python 1.2 A ...