初次体验协程,对比线程有哪些优势(利用阿里库快速引入Quasar)

1. 什么是协程

简单可以理解为理解为用户态线程,在学过操作系统的时候我们知道,线程可以在用户态和内核态之间切换,目前java中所实现的线程都会有自己的上下文,上下文在线程的运行过程中会不断的切换,线程就会不断地从用户态和内核态之间切换。由此带来巨大开销。

协程:我们可以简单的理解为用户态线程,避免了内核态和用户态之间的切换来减少线程上下文切换的开销。

但是JVM原生是不支持这样的操作的。因此如果要在纯java代码里需要使用协程的话需要引入第三方包,如kilim,Quasar。而kilim已经是很久未更新了,接下来我们使用Quasar。

2. Quasar

为了榨干CPU的性能,使得一个资源利用率最大化,在java种引进了fork/jion机制。
fork/jion机制可以参考:https://blog.csdn.net/qq_35688140/article/details/100769876

因为有些fiber可能先执行完成,而work-stealing可以动态的从其他的等等队列偷一个context过来,这样可以最大化使用CPU资源。

3. 关于线程和协程的性能对比

因为Quasar本身并没有提供maven库,这就使得直接使用Quasar需要手动编译安装等等。我们这里直接使用阿里巴巴镜像源下可以直接使用Quasar的maven库。(需要配置maven镜像源为阿里镜像源才可以生效)

pom.xml

	<dependency>
            <groupId>co.paralleluniversegroupId>
            <artifactId>quasar-coreartifactId>
            <version>0.7.9version>
            <classifier>jdk8classifier>
     dependency>

3.1 开启1000000个线程

public class Main {
    public static void main(String[] args) {
        long start = System.nanoTime();
        final CountDownLatch latch = new CountDownLatch(1000000);

        //使用阻塞队列来获取结果。
        for (int i = 0; i < 10000; i++) {
           
            Thread thread = new Thread(new Runnable() {
                @Override
                public void run() {

                    try {
                        latch.await();
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }

                }
            });
            //开始执行
            thread.start();
        }

        long time = System.nanoTime() - start;
        System.out.printf("Tasks took %.3f ms to run%n", time/1e6);

    }
}

花费时间:650.046 ms
初次体验协程,对比线程有哪些优势(利用阿里库快速引入Quasar)_第1张图片

3.2 开启1000000个协程

需要注意的是,引入的同步计数器需是Quasar中的。(3.1使用的同步计数器是jdk中的)


public class Main {
    public static void main(String[] args) throws InterruptedException, ExecutionException {
        long start = System.nanoTime();
        final CountDownLatch latch = new CountDownLatch(1000000);

        //使用阻塞队列来获取结果。
        for (int i = 0; i < 10000; i++) {
            //这里的Fiber就是协程
            Fiber<Integer> fiber = new Fiber<>( () -> {
                latch.await();
            });
            //开始执行
            fiber.start();
        }

        long time = System.nanoTime() - start;
        System.out.printf("Tasks took %.3f ms to run%n", time/1e6);

    }
}

花费时间:214.376 ms
初次体验协程,对比线程有哪些优势(利用阿里库快速引入Quasar)_第2张图片
很明显,使用协程性能上提升了约2倍。

你可能感兴趣的:(并发)