Как правило, тупиков не должно быть только с одной блокировкой. Единственный раз, когда вы можете получить «тупик» с одной блокировкой, это когда один поток может монополизировать блокировку. Т.е. он получает, освобождает, но захватывает, прежде чем другой поток имеет шанс. Java synchronized
не является справедливой блокировкой.
Однако самый простой случай тупика - это когда у вас есть блокировка A и блокировка B. Поток T1 получает блокировку A, в то время как одновременно поток T2 получает блокировку B. T1 выполняет некоторую работу и пытается получить блокировку B. Однако B удерживается T2, поэтому он блокируется. T2 выполняет некоторую работу и пытается получить блокировку B. Он блокируется T1, поэтому блоки T2.
T1 ожидает A, который удерживается T2, и T2 ждет B, который удерживается T1. Так что ни один из них не может добиться прогресса и снять блокировку.
Поэтому я ожидаю, что ваш метод doSomething()
фактически получает другую блокировку в своем теле, вызывая другой код.
Существует общее решение: создать список ваших блокировок, и когда вам нужно несколько блокировок, вы всегда получаете их в одном и том же порядке. В этом случае никаких тупиков не может быть. Однако проблема в том, что вы редко можете создать такой список, потому что сегодня мы почти всегда используем код других пользователей.
По этой причине методы synchronized
on были плохой идеей. Synchronized - это низкоуровневая конструкция; Вы должны использовать его только для очень маленьких блоков кода, которые не вызывают внешний код . Т.е. вы обновляете структуру данных, но не вызываете. Когда вы находитесь в синхронизированном блоке и звоните в другие службы, вы играете в русскую рулетку. Если вам нужно увеличить время, используйте классы в java.util.concurrency
, которые разрешают тайм-ауты. Тайм-ауты - самое простое решение для взаимоблокировок.
Существует много шаблонов для правильного использования синхронизированных. Тем не менее, это очень сложная область. Все, что я знаю о блокировке (и многое другое), я узнал из Обработка транзакций . Хорошей книгой о Java параллелизме является Java Параллелизм на практике .