тупик
Взаимная блокировка — это явление, при котором два или более процессов (потоков) блокируются из-за конкуренции за ресурсы или связи друг с другом в процессе выполнения, без внешней силы они не смогут продвигаться вперед. В это время говорят, что система находится в состоянии взаимоблокировки или в системе есть взаимоблокировка.Эти процессы (потоки), которые всегда ждут друг друга, называются процессами взаимоблокировки (потоками).
Четыре необходимых условия возникновения взаимоблокировки
- Условие взаимного исключения: потоки (процессы) являются эксклюзивными для выделенных ресурсов, то есть ресурс может быть занят только одним потоком (процессом), пока он не будет освобожден потоком (процессом).
- Условия запроса и удержания: когда поток (процесс) блокируется из-за запроса на занятые ресурсы, он будет удерживать полученные ресурсы.
- Условие отсутствия лишения: ресурсы, полученные потоком (процессом), не могут быть принудительно лишены другими потоками до того, как они будут израсходованы, и ресурсы освобождаются только после того, как они будут израсходованы.
- Циклическое условие ожидания: при возникновении взаимоблокировки ожидающий поток (процесс) должен сформировать цикл (аналогичный бесконечному циклу), что приводит к постоянной блокировке.
Как обнаружить
Используйте jstack или jconsole для просмотра стеков потоков.
"Thread-1" prio=10 tid=0x00007fe8c00a0800 nid=0x17cc waiting for monitor entry [0x00007fe8c5031000]
java.lang.Thread.State: BLOCKED (on object monitor)
at DeadLocakTest$DeadThread2.run(DeadLocakTest.java:61)
- waiting to lock <0x00000000af24b248> (a java.lang.Object)
- locked <0x00000000af24b258> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
"Thread-0" prio=10 tid=0x00007fe8c009e800 nid=0x17cb waiting for monitor entry [0x00007fe8c5132000]
java.lang.Thread.State: BLOCKED (on object monitor)
at DeadLocakTest$DeadThread1.run(DeadLocakTest.java:38)
- waiting to lock <0x00000000af24b258> (a java.lang.Object)
- locked <0x00000000af24b248> (a java.lang.Object)
at java.lang.Thread.run(Thread.java:745)
Locked ownable synchronizers:
- None
Thread-1
locked <0x00000000af24b258>
waiting to lock 0x00000000af24b248
Thread-0
locked 0x00000000af24b248
waiting to lock 0x00000000af24b258
Как решить
- Прерывание запроса и удержание: Запрос всех ресурсов одновременно.
- Уничтожение условия отказа от вытеснения: когда поток, занимающий некоторые ресурсы, в дальнейшем обращается за другими ресурсами, если он не может подать заявку на них, он может активно освобождать ресурсы, которые он занимает.
- Разрушьте циклическое условие ожидания: подавайте заявки на ресурсы по порядку и освобождайте ресурсы в обратном порядке.
живой замок
Livelock означает, что задача или исполнитель не заблокированы, потому что не выполняются какие-то условия, в результате чего повторяются попытки, сбои, попытки, сбои. Разница между livelock и deadlock заключается в том, что сущность в livelock постоянно меняет состояние, так называемое «живое», в то время как сущность в deadlock находится в ожидании; livelock может сняться сам по себе, а deadlock — нет.
Для разрешения живых блокировок может быть введена некоторая случайность, например, при обнаружении конфликта приостановка на случайный период времени и повторная попытка. Это время значительно снижает вероятность столкновения. Типичным примером является механизм обнаружения CSMA/CD Ethernet.
блокировка голодания
Голодание: это означает, что если поток T1 занимает ресурс R, поток T2 снова запрашивает блокировку R, поэтому T2 ждет. Т3 также запрашивает ресурс R. Когда Т1 снимает блокировку с R, система сначала одобряет запрос Т3, а Т2 все еще ждет. Затем T4 снова запрашивает блокировку R. Когда T3 снимает блокировку с R, система снова одобряет запрос T4... и T2 может ждать вечно.