【发布时间】:2016-06-17 08:43:00
【问题描述】:
鉴于下面的完整源代码,请解释为什么在 Eclipse 中每次执行此程序都会导致do1() 中的time 比do2() 中的time 大2~3 毫秒。
JVM 是否需要“预热”?
import java.util.concurrent.atomic.AtomicInteger;
import java.util.stream.IntStream;
public class Question {
public static void main(String[] args) {
do1();
do2();
}
public static void do1() {
O obj = new O();
Thread t = new Thread(() -> IntStream.range(0, 100000)
.forEach(e -> obj.incrementN()));
long start = System.currentTimeMillis();
t.start();
try {
t.join();
} catch (InterruptedException e1) {
}
float time = (System.currentTimeMillis()-start)/1000F;
System.out.println(time);
System.out.println(obj);
System.out.println();
}
public static void do2() {
O obj = new O();
Thread t = new Thread(() -> IntStream.range(0, 100000)
.forEach(e -> obj.incrementN()));
long start = System.currentTimeMillis();
t.start();
try {
t.join();
} catch (InterruptedException e1) {
}
float time = (System.currentTimeMillis()-start)/1000F;
System.out.println(time);
System.out.println(obj);
}
}
class O {
private AtomicInteger n = new AtomicInteger(0);
public void incrementN() {
n.getAndIncrement();
}
@Override
public String toString() {
return ""+n.get();
}
}
样本输出:
0.003
100000
0.001
100000
【问题讨论】:
-
如果你这样做会更准确,比如说一千次,然后取平均结果。这可能只是随机性。
-
是的,JVM 需要预热,因为大量使用的代码通过 JIT 系统编译为本机代码。
-
它只是一次结果,平均可以给出更准确的结果。它可以是 O 类的加载时间,在 do1() 中完成一次,然后在 do2() 中不花费时间。
-
我已经多次运行这个程序,
do2()中的time变量总是小于do1()中的time变量。如果do1()和do2()被放置在main()下的循环中,那么是的,所有结果都大约为1 ms,除了第一个或两个给出2~4 ms 的结果。 @Gurpreet Singh 时间计算在new O()之后开始,不确定这是否重要。
标签: java eclipse multithreading performance jvm