Я имею дело с многопоточностью в 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
только в одном потоке (на самом деле по одному на каждое процессорное ядро, которое у меня есть, это программа с интенсивным использованием ЦП), а затем поочередно много раз выполняю другую последовательную обработку. Кажется, что программа не становится быстрее. Может быть, я мог бы найти способ согреться…