多线程为什么两个Java线程(在某些情况下)的速度是一个线程的两倍以上?
文件:示例1。爪哇
public class Example1 implements Runnable {
public void run() {
for(int i = 0; i < 100000000; i++) {
int x = 5;
x = x * 4;
x = x % 3;
x = x + 9000;
x = x * 923;
}
}
public static void task() {
for(int i = 0; i < 100000000; i++) {
int x = 5;
x = x * 4;
x = x % 3;
x = x + 9000;
x = x * 923;
}
for(int i = 0; i < 100000000; i++) {
int x = 9;
x = x * 2;
x = x % 4;
x = x + 3241;
x = x * 472;
}
}
public static void main(String[] args) {
long startTime = System.currentTimeMillis();
Example1.task();
Example1.task();
Example1.task();
Example1.task();
Example1.task();
long stopTime = System.currentTimeMillis();
long runTime = stopTime - startTime;
System.out.println("Run time for one thread: " + runTime);
startTime = System.Example1();
(new Thread(new Example1())).start();
(new Thread(new Example2())).start();
(new Thread(new Example1())).start();
(new Thread(new Example2())).start();
(new Thread(new Example1())).start();
(new Thread(new Example2())).start();
(new Thread(new Example1())).start();
(new Thread(new Example2())).start();
(new Thread(new Example1())).start();
(new Thread(new Example2())).start();
stopTime = System.currentTimeMillis();
runTime = stopTime - startTime;
System.out.println("Run time for two threads: " + runTime);
}
}
文件:示例2。爪哇
public class Example2 implements Runnable {
public void run() {
for(int i = 0; i < 100000000; i++) {
int x = 9;
x = x * 2;
x = x % 4;
x = x + 3241;
x = x * 472;
}
}
}
当我运行它时,它会输出:
Run time for one thread: 1219
Run time for two threads: 281
或者非常接近的东西
为什么会有这样的差异?为什么把它分成两个线程比直接运行要快两倍多
# 1 楼答案
线程上的调用start()会立即返回,因为它只是让线程排队。 线程本身将在一段时间后开始在后台运行
# 2 楼答案
实际上,您根本不需要等待线程完成
启动线程后,必须调用。在其上join()以等待其完成。这里发生的事情是,所有线程都在启动,一旦最后一个线程启动,就给它计时,然后计算停止时间。这意味着您的线程仍在后台运行
编辑:第一个线程花费这么长时间的原因是,您正在进行一系列同步调用,同时创建一个线程并启动它生成一个异步任务
编辑2:以下是第一次测试中发生的事情的餐巾纸序列图: http://www.websequencediagrams.com/cgi-bin/cdraw?lz=TWFpbi0-RXhhbXBsZTE6IFRhc2sgc3RhcnRlZAphY3RpdmF0ZSAAGAgKACEILS0-TWFpbjogZG9uZQpkZQAYEgABWAABWAABgTFlMQo&s=napkin
下面是第二次测试的餐巾纸顺序图: http://www.websequencediagrams.com/cgi-bin/cdraw?lz=TWFpbi0tPkFub255bW91cyBUaHJlYWQ6IFN0YXJ0IEV4YW1wbGUxLnRhc2soKQoACSYyAAEuAAFdAAGBOwCCPjoAgyIGPk1haW46ICJIb3cgbG9uZyBkaWQgdGhhdCB0YWtlPyIKAINmEC0AKwhUYXNrcyBiZWdpbiB0byBmaW5pc2guLi4gKHNvbWUgbWF5IGhhdmUgZW5kZWQgZWFybGllcikK&s=napkin
编辑3:我刚刚意识到第二个序列图将所有箭头指向/same/线程。它们实际上是不同的线程,每次调用
# 3 楼答案
下面是我通过您的代码向线程添加join得到的结果:
所以前面的答案是正确的
编辑:我这样添加了连接。你可以做得更好,但没关系:
你必须加入每个线程。但是,您不会浪费时间等待join(),因为其他线程不会被阻塞。如果该线程在您调用join之前已经完成了它的执行,那么您只需继续下一个线程
还有,你最后的评论是什么意思