Java中的“协程”

createh51周前 (05-16)技术教程2

进程:process

线程:thread

协程:coroutine/feber

引子

最近在重新梳理知识体系,在比较编程语言的时候,发现现在流行的lua go rust kotlin之类都有 协程的概念,而java在这块是比较迟钝的,而像go这类语言内置了协程,可以很容易写出高性能的程序。 什么是”协程“ 众所众知,进程是OS用来分配资源的最小单位,线程是进行任务执行的最小单位,进程与线程都是OS级别的,两者的运行都依赖于cpu的调度与资源分配,进程与线程都属于内核态。而协程是在种轻量级别的线程,CPU根本不知道有协程的使用调度,它运行在用户态,不需要与内核打交道,节省了OS级别的上下文切换 Java中的协程 其实java相比go rust等有点落后,没有内置的协程概念,目前只能使用线程池,事件驱动等形式来支持高性能的程序,java目前有一些协程的类库quasar,提供了纤程的使用,纤程其实就是协程。下面用quasar写个例子来验证一下纤程有多厉害吧。例子很简单,启动100万个线程或者纤程,每个线程或纤程处理2kw次运算。

普通线程类 package com.fqh.review.base.fiber;

package com.fqh.review.base.fiber;

/**
 * @author fqh
 * @Description: java 线程例子
 * @date 2020/7/28下午4:49
 */
public class JavaThread {

  /**
   * 100w个线程,每个线程处理2千万次运算
   * @param argus
   * @throws InterruptedException
   */
  public static void main(String[] argus) throws InterruptedException {
    long begin = System.currentTimeMillis();
    int threadLength=1000000;//100w
    Thread[] threads=new Thread[threadLength];
    for (int i=0;i<threadLength;i++){
      threads[i]=new Thread(()->{
        calc();
      });
    }

    for (int i=0;i<threadLength;i++){
      threads[i].start();
    }
    for (int i=0;i<threadLength;i++){
      threads[i].join();
    }
    System.out.println(System.currentTimeMillis()-begin);
  }

  //2kw次计算
  static void calc(){
    int result=0;
    for(int i=0;i<10000;i++){
      for(int j=0;j<200;j++){
        result+=i;
      }
    }
  }

}
  • 纤程测试类 引入quasarJar
<dependency>
  <groupId>co.paralleluniverse</groupId> 
	<artifactId>quasar-core</artifactId>
  <version>0.7.10</version> 
</dependency>

package com.fqh.review.base.fiber;

import co.paralleluniverse.fibers.Fiber;
import java.util.concurrent.ExecutionException;

/**
 * @author fqh
 * @Description: java 纤程测试用例
 * @date 2020/7/28下午4:48
 */
public class JavaFiber {
  /**
   * 100w个纤程,每个纤程处理2千万次运算
   * @param argus
   * @throws InterruptedException
   */
  public static void main(String[] argus) throws ExecutionException, InterruptedException {
    long begin = System.currentTimeMillis();
    int fiberLength=1000000;//100w
    Fiber<Void>[] fibers=new Fiber[fiberLength];
    for (int i=0;i<fiberLength;i++){
      fibers[i]=new Fiber(()->{
        calc();
      });
    }

    for (int i=0;i<fiberLength;i++){
      fibers[i].start();
    }
    for (int i=0;i<fiberLength;i++){
      fibers[i].join();
    }
    System.out.println(System.currentTimeMillis()-begin);
  }

  //2kw次计算
  static void calc(){
    int result=0;
    for(int i=0;i<10000;i++){
      for(int j=0;j<200;j++){
        result+=i;
      }
    }
  }

}
  • 软件环境: JDK8
  • 机器配置:处理器名称: Intel Core i7 处理器速度: 2.7 GHz 处理器数目: 1 核总数: 4 L2 缓存(每个核): 256 KB L3 缓存: 8 MB 内存: 16 GB

测试结果: 线程大概在50S左右,纤程在4S左右。。 ||

是不是被测试结果惊呆了。。只希望java能尽快把纤程进行内置。这样go rust之类的也就没有什么优势了。。

相关文章

java算法题-在区间范围内统计奇数数目

在leetcode(https://leetcode-cn.com/)上看到一道有趣的算法题:给你两个非负整数 low 和 high 。请你返回 low 和 high 之间(包括二者)奇数的数目。示例...

JVM 深度解析:运行时数据区域、分代回收与垃圾回收机制全攻略

共同学习,有错欢迎指出。JVM 运行时数据区域1. 程序计数器程序计数器是一块较小的内存空间,可看作当前线程所执行的字节码的行号指示器。在虚拟机概念模型里,字节码解释器通过改变这个计数器的值选取下一条...

图解常见的限流算法(计数器、滑动窗口计数、漏桶、令牌桶)

哈喽,大家好呀,我是呼噜噜,好久没有更新文章了,今天我们来聊聊在企业级项目中,常见的几种限流手段的原理及其实现什么场景需要限流随着互联网的业务发展,比如秒杀、双十一、618等这些我们耳熟能详,也有被人...

Java高并发解决方案:轻松应对海量请求

Java高并发解决方案:轻松应对海量请求在当今互联网时代,高并发问题已经成为每个Java开发者绕不开的话题。无论是电商平台的大促活动,还是社交平台的热门话题讨论,都可能瞬间产生海量请求。那么,我们该如...

Java并发工具:CountDownLatch

CountDownLatch是Java并发包(java.util.concurrent)中提供的一种同步工具,用于控制一个或多个线程等待其他线程完成操作。它是一个非常有用的工具类,常用于协调多个线程之...

踩坑!Java集合必学技能:Collection.size()方法深度解析与避坑

一、开发中遇到的问题:动态集合统计的"陷阱"在实际开发中,我们经常需要统计集合中的元素数量。例如,电商订单处理场景中需要实时统计待处理订单数。但如果不理解size()方法的底层逻辑,容...