初次体验协程,对比线程有哪些优势(利用阿里库快速引入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.paralleluniverse</groupId>
            <artifactId>quasar-core</artifactId>
            <version>0.7.9</version>
            <classifier>jdk8</classifier>
     </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
在这里插入图片描述

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
在这里插入图片描述
很明显,使用协程性能上提升了约2倍。

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值