Вы столкнулись с несколькими проблемами здесь:
Слишком умная Java
for (int i=0; i<2000; i++)
result = result.multiply(BigInteger.valueOf(i));
JIT обнаружит это как мертвый код и просто полностью удалит его. Это означает, что ваш код будет завершен за доли миллисекунды. Чтобы исправить это, добавьте result
к ответу, чтобы его нельзя было удалить.
Ваше оборудование ограничено
Больше рабочих потоков не обязательно означает большую пропускную способность, поскольку ваша машина действительно должна быть в состоянии справиться с рабочей нагрузкой. Если вы также запустите JMeter на той же машине, вы не увидите никакого увеличения пропускной способности даже при размере threads >= amount_of_cpus / 2
. Имейте в виду, что если вы используете ЦП Intel, в нем есть гипер-ядра, которые регистрируются как «настоящие» ЦП. , но не буду делать никакой работы. Поэтому, если вы запускаете это на четырехъядерном процессоре Intel, не ожидайте увеличения пропускной способности после 2-го рабочего потока.
Поток занимает время
На самом деле требуется время для управления потоками и переключения между ними. Так что после определенного количества потоков в системе ваша пропускная способность заметно снизится. Ваш шаг от 5 до 50 - это слишком много, чтобы обнаружить это, попробуйте продвинуться шагами в 2 потока.
Резьба хаотична
Порядок выполнения с потоками не определен. Поэтому, если вы запустите достаточно потоков, они начнут украсть время выполнения друг у друга. Некоторые могут завершиться почти мгновенно, в то время как другие будут поставлены в очередь в течение нескольких секунд. На 50 потоках вы увидите намного больше времени для завершения просто потому, что так много потоков постоянно находятся в режиме ожидания. Вы можете убедиться в этом, сравнив минимальное и максимальное время выполнения, которое должно начать расходиться с ростом числа потоков.