Лучший способ избежать взаимоблокировки - убедиться, что все потоки пытаются блокировать и разблокировать объекты в одном и том же порядке. Вот и все.
Следуя этому простому правилу, вероятность взаимоблокировки равна нулю.
Неважно, пытаетесь ли вы распределить все необходимые блокировки за один удар или в течение значительного периода времени, если порядок соответствует. Другими словами, никогда не делайте:
Thread A Thread B
======== ========
lock a lock b
lock b lock a
Это может привести к последовательности:
- A запирает.
- B замки б.
- A пытается заблокировать b, останавливается и ждет.
- B пытается заблокировать a, останавливается и ждет.
Теперь оба потока ожидают от другого освобождения необходимого им ресурса, следовательно, тупик.
Если вы измените поток B
, чтобы он заблокировал a
и b
в этом порядке, тупик станет невозможным.