线程与协程的性能分析

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第4天,点击查看活动详情

本小节我们来做个小实验,验证一下协程和线程的性能,看看前面说过的话,是不是真的,废话少说,show me the code。

线程实验

我们用线程来做一个计算,创建一个线程,之后进入runnable状态,等待cpu分配,之后进入运行状态,执行我们的run方法,run方法我们进行了一个200W次的计算,整体代码如下:

public static void main(String[] args) {
    int threadLength = 10000;
    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();
    }
}

private static void calc() {
    int result = 0;
    for (int i = 0; i < 10000; i++) {
        for (int j = 0; j < 200; j++) {
            result += i;
        }
    }

}

我们这段代码能行嘛?这肯定不行啊, threads[i].start();线程进入可运行状态,可能还没执行,主线程已经走完了,所以我们需要调用join方法,使主线程等待其它线程执行完。加一下这段代码。

for (int i = 0; i < threadLength ; i++){
    try {
        threads[i].join();
    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

然后我们需要记个时,就完成了,完整代码呢如下:

image.png

100个线程,每个线程做200w次运算,耗时:cost-javaThread:59

协程实验

线程改协程呢,就很好改,线程和协程的用法一样,就是原理不一样,所以只需把线程类换成对应的协程就好。

image.png

然后,你直接run起来,它就有个警告:

image.png

是说java-agent没有启动,java-agent就是字节码编程,所以你需要在vm参数加入javaagent:包的路径。

性能分析

然后,我们启动10000个协程,看看效果:

image.png

我们启动10000个线程,看看效果:

image.png

我们启10万线程,看看效果,4秒多:

image.png

我们启100万协程,看看效果,才2秒多:

image.png

效果显著,线程越多,都要到内核态切换,切换成本太高。

猜你喜欢

转载自juejin.im/post/7127052393279127589