java程序使用多线程,能用到cpu的多个核心吗?
网上看了有说能的,有说不能的,最简单的就是自己写个例子去验证。
1,示例1(先上100线程):
public class MyThread1 extends Thread {
public void run () {
for(int i=0;;i++){
System.out.println(this + ":" + i);
}
}
public static void main(String[] args){
for (int i =0;i<100;i++) {
MyThread1 myThread = new MyThread1();
myThread.start();
}
}
}
结果出现了,发现该java进程的cpu使用量小于1个核心,大该只占1个核心的60%左右。
不服,上10000个线程,发现cpu的使用量也不过只占1个核心的80%左右。
什么原因,再看示例2.
2,示例2(上3个线程):
public class MyThread2 extends Thread {
public void run () {
for(int i=0;;i++){
}
}
public static void main(String[] args){
for (int i =0;i<3;i++) {
MyThread2 myThread = new MyThread2();
myThread.start();
}
}
}
果然,上3个线程,就跑满了3个核心,cpu占用达到300%。
为什么示例1在线程中不停的打印字符,就跑不满核心,而示例2不停的做++运算,就能跑满核心呢?
我恍然大悟,原来做打印的时候,进行io操作,cpu不会在这里等,而时去调度其他线程去了,线程被阻塞了,想想每做1次++就要阻塞1次,大部分时间都在阻塞中,基本不占cpu,所以,10000个这样的线程,才跑了1个核心的70%。
我灵光再现,再写示例3,实现打印,但是也跑满核心
示例3(3线程):
public class MyThread3 extends Thread {
public void run () {
for(int i=0;;i++) {
if(i == 1e5) {
System.out.println(this + ":" + i);
i=0;
}
}
}
public static void main(String[] args){
for (int i =0;i<3;i++) {
MyThread3 myThread = new MyThread3();
myThread.start();
}
}
}
结果:这次没有跑满3个核心,但是跑了2.8个核心左右, 所以,在cpu充足的情况下,java线程占cpu的多小,关键在运行计算时间和io访问时间的比例,这样,我们去分析我们的线程时,应该能大致分析出该线程需要吃多少cpu,而且可以通过简单的top命令可以实时查看每个线程所占的cpu,定位到吃cpu异常的线程。