文件:Example1.java
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);
}
}
文件:Example2.java
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;
}
}
}
当我运行它时,它输出:
一个线程的运行时间:1219
两个线程的运行时间:281
或非常接近的东西。
为什么会有这样的差异?为什么将它分成两个线程比直接运行它快两倍?
答案 0 :(得分:19)
你实际上并没有等待线程完成。
启动线程后,必须在其上调用.join()以等待它完成。这里发生的是你的所有线程都在启动,一旦最后一个线程启动,你计时它然后计算停止时间。这意味着您的线程仍在后台运行。
编辑:第一个花费这么长时间的原因是因为你正在进行一系列同步调用,而创建一个线程并启动它会产生一个异步任务。
编辑2:这是第一次测试中发生的情况的餐巾序列图: http://www.websequencediagrams.com/cgi-bin/cdraw?lz=TWFpbi0-RXhhbXBsZTE6IFRhc2sgc3RhcnRlZAphY3RpdmF0ZSAAGAgKACEILS0-TWFpbjogZG9uZQpkZQAYEgABWAABWAABgTFlMQo&s=napkin
编辑3:我刚刚意识到第二个序列图将所有箭头指向/ same / thread。它们实际上是不同的线程,每次调用。
答案 1 :(得分:2)
Thread上的call start()会立即返回,因为它只是将线程排入队列。 一段时间后,线程本身将开始在后台运行。
答案 2 :(得分:1)
以下是我的代码添加到线程的连接:
一个线程的运行时间:566
两个线程的运行时间:294
所以以前的答案都是正确的。
编辑:我以这种方式添加了连接。你可以做得更好,但没关系: Thread[] t = new Thread[10];
(t[0] = new Thread(new Example1())).start();
(t[1] = new Thread(new Example2())).start();
(t[2] = new Thread(new Example1())).start();
(t[3] = new Thread(new Example2())).start();
(t[4] = new Thread(new Example1())).start();
(t[5] = new Thread(new Example2())).start();
(t[6] = new Thread(new Example1())).start();
(t[7] = new Thread(new Example2())).start();
(t[8] = new Thread(new Example1())).start();
(t[9] = new Thread(new Example2())).start();
for (Thread t1: t) {
try {
t1.join();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
您必须加入每个帖子。但是,您不会在join()中浪费您的时间,因为其他线程未被阻止。如果线程在您调用join之前已经完成了它的执行,那么您只需继续下一个线程。
另外,你的上一条评论是什么意思?