Как получить гарантированный дедлок?
Сначала поговорим о том, что это такое. Deadlock – это взаимная блокировка, ситуация, когда два или более потока «наступают друг-другу на хвост» – зависают в вечном ожидании ресурсов, захваченных друг другом.
Livelock – похожая проблема, с тем лишь отличием, что потоки не останавливаются, а вместо этого зацикливаются, выполняя одни и те же бесполезные действия, ходят по кругу.
Стандартный подход к обеспечению гарантии защиты от дедлока – установка строгого порядка взятия блокировок. Если для мониторов A и B соблюдается всеобщий порядок захвата AB (и соответственно отпускания BA), то ни с одним потоком не случится попасть на ожидание B, успешно при этом захватив A.
Из этого можно догадаться, простой способ
гарантировать возможность дедлока – явно нарушить это условие.
Нарушение условия даст дедлок «скорее всего когда-нибудь». Чтобы получить его
точно и
с первого раза, нужно гарантировать, что оба потока окажутся на этапе между захватами одного и другого ресурса в одно время. Это можно сделать множеством способов, в примере ниже использован
CyclicBarrier
.
Вопрос дедлоков – одна из краеугольных тем
параллельных вычислений, уходящая далеко за рамки этого вопроса. Для дальнейшего изучения рекомендуются статьи на википедии
про дедлоки, про
задачу об обедающих философах как классическая иллюстрация проблемы, и глава 10.1
Java Concurrency in Practice.