В предыдущем посте я показал механизм приостановки потоков на основе такой штуки как LockSupport, но не рассказал как на самом деле устроен этот механизм.
Покопавшись в исходниках JVM я выяснил что методы
LockSupport.park() и LockSupport.unpark() под капотом обращаются к следующим системным вызовам Linux:void Parker::park(...) {
// специальный системный вызов который приостанавливает поток и ждет пока не будет вызван сигнал
pthread_cond_wait(...)
}
void Parker::unpark() {
// сигнал который снова возобновляет выполнение потока
pthread_cond_signal(...)
}Оба вызова принимают на вход мьютекс, который захватывается когда поток был возобновлен и освобождается когда поток был приостановлен, это дополнительная синхронизация для кода который должен быть атомарно выполнен до приостановки или после возобновления потока.
По итогу происходит вызов планировщика процессов Linux, который либо исключает поток из планирования (pthread_cond_wait), это значит что CPU не будет его выполнять, либо обратно добавляет в очередь планирования (pthread_cond_signal), где поток будет получать определенное количество времени от CPU для своего исполнения.
P.S. В прошлом году я опубликовал статью на Github'е о том как приостанавливается жизненный цикл в Android, так вот, там используется другой системный вызов, он называется epoll, главное его отличие в том что он реагирует на операции ввода-вывода, а не на сигналы.
Всем хорошего кода!