Почему фиктивный поток (только спящий в короткие промежутки времени) улучшает производительность другого потока?

Мы используем ScheduledExecutorService.scheduleAtFixedRate для выполнения задачи ввода-вывода каждые 100 мс. (Фактическая операция ввода/вывода выполняется сторонней библиотекой, и мы точно не знаем, что происходит внутри.)

Иногда поддержание интервала в 100 мс имеет некоторые проблемы, и мы возвращаемся к 500 мс. Так как это ввод/вывод, мы не были удивлены, но мы наблюдали странное поведение:

Если конкретный поток запускается, мы соответствуем 100 мс. Если этот поток не запущен, мы возвращаемся к 500 мс.

Метод запуска этого конкретного потока выглядит следующим образом:

while(active){
  try {
    Thread.sleep(delay);
  } catch (InterruptedException e) {
    Thread.currentThread().interrupt();
    break;
  }
//some more stuff
}

В основном, когда мы используем небольшую задержку, например 5 мс, мы получаем лучшую производительность в библиотеке. Когда мы используем более длительные задержки, например, 1000 мс, производительность значительно ухудшается.

Это также, похоже, зависит от платформы, так как мы не смогли воспроизвести проблему. (Java 8, Windows 10)

Все, что мы знаем, это то, что это определенно короткий сон() -call, вызывающий улучшение, поскольку мы могли бы решить проблему, запустив фиктивный поток, просто спящий в короткие промежутки времени.

Любое объяснение было бы полезно, чтобы понять, что происходит :-)

--- редактировать

Еще интереснее: если мы добавляем не один, а два новых потока только для коротких интервалов ожидания, это добавляет немного производительности. Не так важно, как в первом потоке, но все равно 20%.

--- редактировать 2

Система, в которой мы можем наблюдать за поведением: Intel Atom E3845 Windows 10

Система, в которой мы не можем ее воспроизвести: Intel i7-5820K Windows 10

Мы не можем найти исходный код, но библиотека, кажется, работает однопоточно (новые потоки не созданы) и создает соединение Socket.

Ответ 1

Обычной практикой является предоставление очень короткого "перерыва", чтобы позволить другим потокам иметь свой ход, в противном случае один поток занимал бы каждый ход.

Ответ 2

Мое мнение о Thread.sleep в бесконечном цикле - плохая идея, а не хорошая практика программирования. В моем опыте программирования я понял это в большем количестве ситуаций. Потому что ваш поток будет съедать циклы ЦП, когда мы используем бесконечный цикл в потоке. Это излишне займет ваши циклы ЦП. Найдите другие альтернативные методы для выполнения вашей работы в зависимости от вашего варианта использования. Вы можете проверить это, включив виртуальную JVM и наблюдая за своей программой. Который четко покажет, где на самом деле проблема, и вы можете ясно увидеть эту нить бесконечного цикла как одного из виновников.