多线程减慢程序的速度
根据我的理解,越来越多的threads
或进入并行会减少时间,但在这里,我看到一个缓慢的Object.hashCode
,它占用了两倍的时间来计算默认的哈希码对同一数量的对象运行4个线程vs 1个线程。多线程减慢程序的速度
我认为这需要花费相当的时间或更少的时间来并行执行此操作。
但是当我们运行下面的代码。我们可以看到,每个线程都有相同的工作量,因此您希望运行4个线程可能需要大约与运行单个线程相同的时间。
我看到~4秒为2.3秒,而1秒为0.9秒。
public class Test {
private static final int THREAD_COUNT = 1;
private static final int ITERATIONS = 20000000;
public static void main(final String[] args) throws Exception {
long start = System.currentTimeMillis();
new Test().run();
System.err.println(System.currentTimeMillis() - start);
}
private final ExecutorService service = Executors.newFixedThreadPool(THREAD_COUNT, new ThreadFactory() {
private final ThreadFactory factory = Executors.defaultThreadFactory();
@Override
public Thread newThread(final Runnable r) {
Thread thread = factory.newThread(r);
thread.setDaemon(true);
return thread;
}
});
private void run() throws Exception {
Callable<Void> work = new java.util.concurrent.Callable<Void>() {
@Override
public Void call() throws Exception {
for (int i = 0; i < ITERATIONS; i++) {
Object object = new Object();
object.hashCode();
}
return null;
}
};
@SuppressWarnings("unchecked")
Callable<Void>[] allWork = new Callable[THREAD_COUNT];
Arrays.fill(allWork, work);
List<Future<Void>> futures = service.invokeAll(Arrays.asList(allWork));
for (Future<Void> future : futures) {
future.get();
}
}
}
注:我看到这篇文章C# Multithreading但因为它是C#所以我能够掌握它,有人能帮助我理解从JVM的角度
相同的,如果我走"new Object()"
在循环之外,我看到相对多线程性能的显着提高。
似乎"new Object()"
将消除GC干扰。
在这种情况下,默认的hashCode涉及:
- 计算一个
hashcode
- 经由原子
compare-and-swap
操作
在紧张的使用原子CAS
的安装此进object
头循环有效地串行化功能代码的核心部分,导致连续执行相当大比例的"work loop"
。
感谢刚刚在谷歌上搜索答案时发现... :) –
@ GhostCat-不,我现在得到了我的答案,明白每一件事情 –
线程并没有真正做任何工作,因为它只是放弃了'hashCode()'的结果。所以JIT编译器可能会跳过'call()'内的整个循环,除非我错了。 'call()'方法目前看起来很没用,因为它总是返回'null'。 –
为了记录:您已阅读此:http://stackoverflow.com/questions/504103/how-do-i-write-a-correct-micro-benchmark-in-java – GhostCat
在查看代码后,它应该要注意的是,如果1个线程执行W个工作量(操作),则N个线程执行N * W个操作。因此,并行减少执行时间并非如此。这个代码根本不需要多线程。 – Eugene