Что такое 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 без возможности переключения.