LeetCode专题 分而治之
zhh-4096
2019-10-06 05:05:45 发布
乘着失眠,把一个疑问想了想:
线程数到底要配多大?

我的笔记本电脑的cpu是双核四个超线程,起初我以为启动jvm后只需开4个java线程就是最理想的状态了,单纯的以为只要这4个线程一直处于运行状态一直有活干就不会被os轻易剥夺执行权,所以至少理论上是最优配置。

可是这两天的性能测试打脸了,开100个线程跑同样的数据量,得到的读写性能指标都比开4个线程时好得多。我cpu才双核四个超线程,跑4个java线程不是刚好够吗?至少理论上线程上下文切换开销都大大减少了,为何开100个反而更好呢?

后来我想到windows的线程调度是抢占式的,并且真实的运行环境里还有大量进程和线程呢,并不是只有我jvm里的那些java线程。就算这4个java线程一直没有被阻塞,os也不会时时刻刻都让它们霸占着cpu的,否则我在做性能测试时连鼠标都点不动了。

也就是说,os还是会把4个java线程的执行权随时剥夺的,然后给其他线程(也包括其他java线程)执行的机会。如果我开了100个线程,那么其他96个线程也可能被os调度到啊,也就是os刚剥夺了那4个java线程之一后,又可能有很大概率调度到另一个java线程来运行,如果只有4个java线程,那可能就调度到其他非java线程了。

所以如果让4个线程处理100万条数据,当其中一个java线程被临时剥夺cpu执行权后,就少了一个处理的机会了,空等在那里,如果是分给100个线程处理,cpu还可能调度到另一个java线程,那么在一个时间段内java线程们得到执行的机会可能更多,所以结束得更快。

当然,线程也不是开越多越好的,毕竟也要占内存的,最好还是实际测试一下,看看线程数开到多大后性能测试结果就趋于稳定了,此时就是最佳配置。

同时也说明了当你在同一台机器上既跑数据库又跑客户端时测出的结果有多不靠谱,做测试时也尽可能停掉其他多余的程序,否则都是会受到干扰的。