Gymterview
middle

Что такое busy spin?

Busy spin (активное ожидание) — это техника, при которой поток ожидает наступления условия, выполняя пустой цикл, вместо того чтобы отдавать процессорное время через wait(), sleep() или yield().

Пример
// Busy spin — поток не уступает процессор
while (!condition.isReady()) {
    // Пустое тело цикла — «крутимся» на процессоре
}

// С Thread.onSpinWait() (Java 9+) — подсказка процессору
while (!condition.isReady()) {
    Thread.onSpinWait(); // hint: процессор может снизить энергопотребление
}

Зачем это нужно? Когда поток уступает процессор (через sleep(), yield(), park()), операционная система может перенести его на другое ядро при возобновлении. Это приводит к перестройке кэша процессора (cache migration), что является дорогой операцией.

Busy spin сохраняет поток на том же ядре, поэтому данные остаются в L1/L2-кэше. Это критично в системах с микросекундными задержками (low-latency).

Когда применять:

Сценарий Подходит busy spin?
Ожидание < 1 мкс Да
Ожидание > 100 мкс Нет — лучше LockSupport.parkNanos()
Высоконагруженные финансовые системы Да (LMAX Disruptor)
Обычные серверные приложения Нет — расход CPU не оправдан

Thread.onSpinWait() (Java 9+) — специальная подсказка JVM/процессору, что поток выполняет busy spin. На x86 транслируется в инструкцию PAUSE, которая снижает энергопотребление и уменьшает конкуренцию за ресурсы процессора между гиперпотоками (hyper-threads).

Аналогия: busy spin — это когда вы стоите у двери и каждую секунду дёргаете ручку, проверяя, не открыли ли. sleep() — вы садитесь на скамейку и ставите будильник. Busy spin дороже (вы постоянно заняты), но вы реагируете мгновенно, как только дверь откроется.

На собеседовании вопрос про busy spin проверяет понимание low-level оптимизаций. Хороший ответ включает упоминание cache locality, Thread.onSpinWait() и примеры (Disruptor, LMAX). Также стоит отметить, что с Virtual Threads busy spin антипаттерн — он блокирует carrier thread без возможности переключения.