여러 자물쇠 A, B 및 C가있을 때마다 코드가 동일한 순서로 해당 잠금을 획득하려는 시도를 보장하지 않으면 교착 상태를 가질 수 있습니다.
final Lock A = new ReentrantLock();
final Lock B = new ReentrantLock();
final Lock C = new ReentrantLock();
A, B, C 또는 C, B, A 또는 A, C, B- 순서가 일관된 한 중요하지 않습니다.
A, B, C에 대한 코드 경로가 하나 있고 C, B, a에 대한 시도가 하나있을 때 문제가 발생합니다.
A와 C가 모두 개최되기 때문에 아마도 추측 할 수 있듯이,이 둘 중 하나는 B를 얻고 두 가지 모두 교착 상태가 될 것입니다. (일명 리소스 잠금 그래프에주기가 있습니다)
공식적으로 말하는 교착 상태가 발생할 수 있습니다 경우에만 다음 모든 조건은 다음과 같습니다.
- 선점 없음 :이 시스템은 할당 후 리소스를 자유롭게하지 않습니다. 그들은 보유 과정에서만 해제 할 수 있습니다.
- 원형 대기 : 위에서 논의 됨.
- 상호 배제 : 하나의 프로세스 만 주어진 시간에 리소스를 사용할 수 있습니다.
- 자원 보유 : 프로세스는 현재 하나 이상의 리소스를 보유하고 있으며 다른 프로세스에서 보유한 추가 리소스를 요청/기다리고 있습니다.
최상의 솔루션은 주문이 일관되거나 더 높은 (단일) 레벨에서 잠그는 것입니다. 또 다른 옵션은 잠금을 시도하는 동안 타임 아웃을하는 잠금 라이브러리를 사용하는 것입니다 (또는 조건을 사용하고이를 수행하는 래퍼를 작성하십시오). 그러나 그 접근법은 희미한 마음을위한 것이 아닙니다. 이것의 일부 구현은 임의의 시간을 기다리고 다시 시도하지만 자물쇠 횟수가 증가함에 따라 비효율적 일 수 있습니다.
자원:
- 다음은 Java의 교착 상태 분석에 대한 실용적인 기사입니다.http://www.journaldev.com/1058/java-deadlock-example-and-to-analyze-deadlock-situation
- Jcarder와 같은 오픈 소스 도구를 사용하여 교착 상태를 찾을 수도 있습니다.http://www.jcarder.org/ 큰 덤프가있는 프로그램의 경우 더 쉬운 덤프 파일을 집어 넣을 수 있습니다.
추신 : 나는 당신의 코드의 많은 부분을 제대로 형식화하지 않았으며 최소한의 예제가 아니기 때문에 실제로 당신의 코드를 많이 읽지 않았습니다 (즉, 우리의 목적에 맞는 장황). 그러나이 조언은 이론적 인 관점에서 질문에 답해야합니다.