#java #multithreading #parallel-processing
#java #Многопоточность #параллельная обработка
Вопрос:
У меня есть простое Java-приложение, которое в основном увеличивает счетчик в 600 миллионов раз. Я разделил эту задачу на несколько потоков, каждый из которых увеличивает свой собственный счетчик и, наконец, суммирует эти счетчики.
Как ни странно, наличие большего количества потоков, чем ядер, обеспечивает лучшую производительность:
Пример (на Intel I7-9850H с шестью ядрами) для среднего времени вычисления:
- Наличие 6 потоков, каждый с шагом 100 м, дает 97 мс
- Наличие 60 потоков, каждый с шагом 10 м, дает 61 мс
AFAIK Java сопоставляет каждый поток с реальным системным потоком.
Есть идеи, почему это происходит?
РЕДАКТИРОВАТЬ:
возможно ли, что причина в том, что на моем компьютере много других запущенных процессов и потоков, поэтому конкуренция из 60 потоков со всеми остальными обитателями лучше, чем только 6 потоков, конкурирующих за ресурсы процессора?
Код метода инкремента:
private static void incrementWithLockFree(long increments, int threads) throws InterruptedException {
final long[] numbers = new long[threads];
ExecutorService threadPool = Executors.newFixedThreadPool(threads);
for (int task = 0; task < threads; task ) {
int finalTask = task;
threadPool.submit(() -> {
for (long increment = 0; increment < increments; increment ) {
numbers[finalTask] ;
}
});
}
threadPool.shutdown();
threadPool.awaitTermination(1, TimeUnit.DAYS);
long number = 0;
for (long num : numbers) {
number = num;
}
System.out.println(number);
}
Ответ №1:
В моей системе меньшее количество потоков работает лучше.
Возможно ли, что причина в том, что на моем компьютере много других запущенных процессов и потоков, поэтому конкуренция из 60 потоков со всеми остальными обитателями лучше, чем только 6 потоков, конкурирующих за ресурсы процессора?
ДА.
В случае, если это реальный вариант использования, взгляните на LongAdder
, который оптимизирован для сценариев многопоточных счетчиков.