香港挂牌全篇最完整篇+香港挂牌彩图2020,香港挂牌 香港挂牌全篇最完整篇+香港挂牌彩图2020,香港挂牌

关于Java多线程是否并行执行的问题

理论上,Java的多线程在多CPU(或者多内核)情况下,应该是并行处理的,即将多个线程均匀分布到多个CPU上去执行,这样的话,理论上做"多个任务"只需要花"做一个任务"的时间。

那么实际情况怎样呢?

下图是我的电脑配置情况,为4核的CPU:

这样理论上可以并行执行4个线程。

我们先写一个用来做测试的方法(这个方法是随便写的,主要是为了拥有一定的计算量,避免时间过短难以观察)

/**

* 静态方法,用于测试

*/

public static void method() {

double a = Math.random() * 10000000;

a /= 2;

double c = a + 2;

}

思路就是分别采用单线程和多线程,多次执行这个方法,看它们在时间消耗上的差别。

第一步:用单线程跑分别跑1000万次和250万次method方法:

/**

* 单线程

*/

public class Test01 {

public static void main(String[] args) {

/**

* 单线程跑1000万次

*/

long begin = System.currentTimeMillis();

for (int j = 0; j < 10000000; j++) {

double a = Math.random() * 10000000;

a /= 2;

double c = a + 2;

}

long end = System.currentTimeMillis();

System.out.println("单线程跑1000万次需耗时:" + (end - begin) / 1000.0 + "秒");

/**

* 单条线程跑250万次,目的是和在多线程情况下执行250万次进行对比

*/

long begin2 = System.currentTimeMillis();

for (int j = 0; j < 10000000 / 250; j++) {

method();

}

long end2 = System.currentTimeMillis();

System.out.println("单线程跑100万次需耗时:" + (end2 - begin2) / 1000.0 + "秒");

}

/**

* 静态方法,用于测试

*/

public static void method() {

double a = Math.random() * 10000000;

a /= 2;

double c = a + 2;

}

}

结果如下:

第二步:使用4个线程,每个线程跑250万次同一个方法。

代码:

/**

* 4个线程,每个线程跑250万次测试方法

*/

public class Main {

public static void main(String[] args) throws Exception {

/** 创建4个线程并开始执行 */

for (int i = 0; i < 4; i++) {

new Thread(new SonThread()).start();

}

/** 让main线程进入休眠状态,等待各个线程执行完毕 */

Thread.sleep(60000);

}

/**

* 子线程

*/

static class SonThread implements Runnable {

@Override

public void run() {

/**

* 多线程的每个子线程跑250万次

*/

long begin = System.currentTimeMillis();

for (int j = 0; j < 10000000 / 4; j++) {

method();

}

long end = System.currentTimeMillis();

System.out.println(Thread.currentThread().getName() + "耗时:" + (end - begin) / 1000.0 + "秒");

}

}

/**

* 静态方法,用于测试

*/

public static void method() {

double a = Math.random() * 10000000;

a /= 2;

double c = a + 2;

}

}

执行结果如下:

第三步:对比单线程和多线程执行结果的不同,并分析其原因。

先看总体上,单线程执行1000万次方法,耗时0.29秒。而多线程情况下,耗时最长的线程用了1.22秒,最少的也用了0.88秒,注意,这还是在单个线程只执行250万次的情况下。也即,总体上采用多线程执行1000万次同一方法需要消耗1.22秒。

再来看单个子线程的情况,在单线程中,执行250万次测试方法共耗时0.07秒,而同样的方法在多线程的子线程中执行相同次数(250万次),花费的时间在0.88~1.22秒之间,差异巨大。

那么为什么会出现这种问题呢?为什么理论上可以节约大量时间的多线程,却比单线程耗时更多呢?

参考 链接 这篇文章,发现在线程数较少的情况下,并不会分配到多个CPU上,而是在单CPU中执行!而我们在操作系统相关课程中学过,CPU在执行多个进程(线程可以看作轻量级进程)时,是把一段时间分成很多个时间片来分配的,在这个例子中,我们的多线程创建了4个子线程,CPU把资源分配给这个Java程序后,程序内部有4个线程共享这个时间片,也即子线程轮流被分配更小的时间片来执行,而一个时间片不足以把单个线程跑完,于是要等待下一个时间片的到来。而在单线程模式下,程序获得时间片后,由于程序内部只有1个线程,CPU的时间片全部分给这个主线程,从头到尾执行完毕。期间节约了等待获取时间片和线程切换带来的时间损耗,所以总耗时比多线程更少。

还有一种解释,就是Java中创建的线程并不等价于操作系统中的进程,并不是由操作系统直接进行调用的。要知道,Java程序运行在JVM上,而JVM又是运行在OS之上的一个进程,所以我们创建的线程都包含在JVM这个进程当中。JVM进程在获得操作系统的CPU资源后,会根据某种调度算法,调度我们创建的4个线程进行工作,而JVM进程本身获取到的CPU资源就有限,再分配给多个线程后,每个线程获取的资源就更加有限。在这种情况下,相当于1个CPU资源,全部用来执行单个任务,和把任务均匀分解成4个子线程,由于子线程不能一次性执行完,线程调度过程就损失了很多时间。于是乎,就出现了多线程比单线程更耗时的情况。

总结一下,同样的程序,多线程跑比单线程跑耗时更长,是因为每个子线程因为获得的资源有限,不能一次性执行完毕,会等待其它线程的执行。而整体上多线程的执行时间(即子线程中耗时最长的)仍然大于单线程,是因为线程调度也会花费时间。

那么多线程不能起到这个作用,为什么还要有多线程呢?首先,在这个例子里,并没有完全发挥到多线程的优势,因为它没有真正并行,而只是并发。如果分配到多个CPU上做到真正并行,那么时间必然会得到很大程度的缩短。其次,多线程的意义其实在于多个任务宏观上同时执行。

免责声明:本文仅代表文章作者的个人观点,与本站无关。其原创性、真实性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容文字的真实性、完整性和原创性本站不作任何保证或承诺,请读者仅作参考,并自行核实相关内容。

/style/images/nopic.gif
我要收藏
赞一个
踩一下
分享到

分享
评论
首页
分享到:QQ空间新浪微博腾讯微博人人网微信