Я имею дело с многопоточностью в Java, и, как кто-то указал мне, я заметил, что потоки нагреваются, они становятся быстрее, поскольку они многократно выполняются.Я хотел бы понять, почему это происходит и связано ли это с самой Java или является ли это обычным поведением каждой многопоточной программы.
Код (автор Питер Лоури), который иллюстрирует это, следующий:
for (int i = 0; i < 20; i++) {
ExecutorService es = Executors.newFixedThreadPool(1);
final double[] d = new double[4 * 1024];
Arrays.fill(d, 1);
final double[] d2 = new double[4 * 1024];
es.submit(new Runnable() {
@Override
public void run() {
// nothing.
}
}).get();
long start = System.nanoTime();
es.submit(new Runnable() {
@Override
public void run() {
synchronized (d) {
System.arraycopy(d, 0, d2, 0, d.length);
}
}
});
es.shutdown();
es.awaitTermination(10, TimeUnit.SECONDS);
// get a the values in d2.
for (double x : d2) ;
long time = System.nanoTime() - start;
System.out.printf("Time to pass %,d doubles to another thread and back was %,d ns.%n", d.length, time);
}
Результаты:
Time to pass 4,096 doubles to another thread and back was 1,098,045 ns.
Time to pass 4,096 doubles to another thread and back was 171,949 ns.
... deleted ...
Time to pass 4,096 doubles to another thread and back was 50,566 ns.
Time to pass 4,096 doubles to another thread and back was 49,937 ns.
Т.е. он становится быстрее и стабилизируется около 50 нс.Почему это так?
Если я запускаю этот код (20 повторений), затем выполняю что-то еще (например, постобработку предыдущих результатов и подготовку к другому раунду многопоточности), а затем выполняю тот же Runnable
для того жеThreadPool
еще для 20 повторений, он будет уже подогрет, в любом случае?
В моей программе я выполняю Runnable
только в одном потоке (фактически по одному на каждое ядро обработки, этоПроцессор-интенсивная программа), затем некоторые другие последовательные обработки поочередно много раз.Похоже, программа не работает быстрее.Может быть, я смогу найти способ согреть его ...