Я искал решения онлайн, этот ответ на Quora, кажется, подразумевает, что время ожидания для блокировки ввода-вывода может быть запланировано для использования для других задач.Верно ли это, особенно для блокирующих сокетов Java?
Обычные потоки Java отображаются в потоки уровня ОС один на один.Они эквивалентны.Так что да, это верно для Java, и на самом деле любой другой язык.Если только он не использует Green Threads или неблокирующий ввод / вывод.
В таком случае, почему бы мне не получить линейное масштабирование с количеством потоков?
Подумайте о том, что вы делаете, с точки зрения процессора.Процессор выполняет дорогостоящее переключение контекста и позволяет запускать некоторые потоки.Этот поток использует ЦП в течение очень короткого промежутка времени для подготовки сетевого вызова, а затем он блокируется на длительное время (миллисекунды довольно много для ЦП, работающего на частоте 3 ГГц).
Таким образом, каждый поток выполняет лишь небольшую часть работы, прежде чем потребуется другое переключение контекста.Это означает, что большая часть времени ЦП тратится на переключение контекста вместо выполнения полезной работы.
Сравните это с потоком, выполняющим задачу с привязкой к ЦП .Переключение контекста занимает то же время.Но когда задается задача, связанная с ЦП, ей удается долго использовать ЦП, что делает переключение контекста более дешевым по сравнению с ним.Это увеличивает общую загрузку ЦП.
Итак, с одной стороны, вы видите более высокие скорости с каждым новым потоком, потому что вы по существу выполняете больше параллельных операций ввода-вывода.С другой стороны, каждый новый поток добавляет стоимость.Таким образом, предельное преимущество каждого дополнительного потока каждый раз немного меньше.Если вы продолжите добавлять потоки, в какой-то момент вы даже достигнете точки, где скорость будет падать с каждым новым потоком.