Выполняя многопоточный код, компьютер распределяет потоки между физическими ядрами ЦП. Это означает, что чем больше число потоков превышает количество ядер, тем меньше вы получаете выгоды от каждого потока. В вашем примере количество потоков увеличивается с количеством задач. Таким образом, с ростом числа задач каждое ядро процессора вынуждено обрабатывать все больше и больше потоков. В то же время вы можете заметить, что разница между numthreads = 1
и numthreads = 4
очень мала. Потому что в этом случае каждое ядро обрабатывает только несколько (или даже только один) поток. Не устанавливайте количество потоков намного больше, чем количество физических потоков ЦП, потому что это не имеет большого смысла.
Кроме того, в вашем примере вы пытаетесь сравнить, как разное количество потоков выполняет с разным количеством задач . Но чтобы увидеть эффективность многопоточного кода, вы должны сравнить, как различное число потоков выполняет с одинаковым количеством задач . Я бы изменил пример следующим образом:
int threadNumber = 16;
int taskNumber = 200;
//...task method
final ExecutorService executorService = Executors.newFixedThreadPool(threadNumber);
final List<Callable<Void>> tasks = new ArrayList<>();
while (taskNumber-- > 0) {
tasks.add(task);
}
long start = System.currentTimeMillis();
for (Future<Void> future : executorService.invokeAll(tasks)) {
future.get();
}
long end = System.currentTimeMillis() - start;
System.out.println(end);
executorService.shutdown();
Попробуйте этот код для threadNumber=1
и, скажем, threadNumber=16
, и вы увидите разницу.