进程:process 线程:thread 协程:coroutine/feber

引子

最近在重新梳理知识体系,在比较编程语言的时候,发现现在流行的lua go rust kotlin之类都有 协程的概念,而java在这块是比较迟钝的,而像go这类语言内置了协程,可以很容易写出高性能的程序。

什么是”协程“

众所众知,进程是OS用来分配资源的最小单位,线程是进行任务执行的最小单位,进程与线程都是OS级别的,两者的运行都依赖于cpu的调度与资源分配,进程与线程都属于内核态。而协程是在种轻量级别的线程,CPU根本不知道有协程的使用调度,它运行在用户态,不需要与内核打交道,节省了OS级别的上下文切换

Java中的协程

其实java相比go rust等有点落后,没有内置的协程概念,目前只能使用线程池,事件驱动等形式来支持高性能的程序,java目前有一些协程的类库quasar,提供了纤程的使用,纤程其实就是协程。下面用quasar写个例子来验证一下纤程有多厉害吧。例子很简单,启动100万个线程或者纤程,每个线程或纤程处理2kw次运算。

普通线程类

```java
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之类的也就没有什么优势了。。
进程: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;

/**
 * @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之类的也就没有什么优势了。。