携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第5天,点击查看活动详情
昨天我们分析了一下进程和协程的性能,并且用实战的方式给大家演示了实际性能的差异,但是大家应该还记得协程是在线程里面的,那怎么来看呢?到底有多少协程在线程里面呢?今天我们就来看下。
协程代码分析
我们打一下断点,看一下线程
从上到下分别是main主线程、指令监听器线程和这个协程的时间调度线程还有垃圾回收线程。
没有协程,接着往下滑,能看到8个协程工作线程:
这个forkjoin是一个异步框架,一共是8
个线程,10万个协程才8个线程切换,相当于一个线程里面有12500
个协程,然后我们增加线程数量到100
万。
可以发现协程增加一倍,线程没有变还是8
个,这就是为啥协程高效的原因,协程本来是go先搞的,后来java也怕没有未来也跟着搞起来了,你如果增加100
万线程,那就是100
万。
多线程和单线程性能
多线程一定比单线程快嘛?其实不一定,是有一个临界值的,在这个范围内,单线程快,我们来用代码演示一下:
private static final long count = 1000000000l;
public static void main(String[] args) {
serial();
try {
concurrency();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
private static void serial() {
long start = System.currentTimeMillis();
int a = 0;
for (long i = 0; i < count; i++) {
a += 5;
}
int b = 0;
for (long i = 0; i < count; i++) {
b--;
}
long time = System.currentTimeMillis() - start;
System.out.println("serial:" + time + "ms);
}
private static void concurrency() throws InterruptedException {
long start = System.currentTimeMillis();
Thread thread = new Thread(new Runnable() {
@Override
public void run() {
int a = 0;
for (long i = 0; i < count; i++) {
a += 5;
}
}
});
thread.start();
int b = 0;
for (long i = 0; i < count; i++) {
b--;
}
thread.join();
System.out.println("concurrency :" + (System.currentTimeMillis() - start) + "ms");
}
- 我们进行了10亿次计算的效果:串行花费:
serial:613ms
,并发花费:concurrency :315ms
- 我们进行了1亿次计算的效果:串行花费:
serial:64ms
,并发花费:concurrency :39ms
- 我们进行了1千万次计算的效果:串行花费:
serial:10ms
,并发花费:concurrency :6ms
- 我们进行了1百万次计算的效果:串行花费:
serial:2ms
,并发花费:concurrency :2ms
此后一路持平,直到计算次数达到1000次,serial:0ms,并发花费:concurrency :1ms
当然这个计算结果跟电脑性能有关系,就是个实验数据。