Лучше ли блокирующий или неблокирующий параллелизм зависит от того, сколько времени вы ожидаете, чтобы ожидать получения ресурса, на котором вы ожидаете.
С ожиданием блокировки (то есть mutex lock, на языке C), ядро операционной системы переводит ожидающий поток в спящий режим.Планировщик ЦП не будет выделять ему время до тех пор, пока после требуемый ресурс не станет доступным.Преимущество здесь в том, что, как вы сказали, этот поток не будет потреблять ресурсы ЦП, пока он находится в спящем режиме.
Однако есть один недостаток: процесс перевода потока в спящий режим, определение того, когда он долженпробуждение и повторное его включение является сложным и дорогостоящим и может свести на нет экономию, достигнутую благодаря тому, что поток не потребляет ЦП во время ожидания.Кроме того (и, возможно, из-за этого), ОС может выбрать , а не , чтобы разбудить поток сразу после того, как ресурс станет доступным, поэтому блокировку можно ожидать дольше, чем необходимо.
Неблокирующее ожидание (также известное как spinlock ) действительно потребляет ресурсы ЦП во время ожидания, но экономит затраты на перевод потока в спящий режим, определение, когда его следует разбудить, и пробуждение.Он также может реагировать быстрее, когда блокировка становится свободной, так как она меньше прихоти ОС с точки зрения того, когда она может приступить к выполнению.
Итак, как очень общее правило, вы должныпредпочитайте спин-блокировку, если вы ожидаете только короткое время ожидания (например, несколько циклов ЦП, которые могут потребоваться для завершения другим потоком записи в ConcurrentHashMap
).При более длительном ожидании (например, при синхронизированном вводе-выводе или количестве потоков, ожидающих одного сложного вычисления), мьютекс (блокирующее ожидание) может быть предпочтительным.