시스템에 있는 다중 작업이 동일한 오브젝트에 액세스하여 이 오브젝트를 조작해야 할 수 있습니다. ILock은 공유 오브젝트에 대한 독점 액세스를 부여하는 프로토콜을 정의합니다. 작업이 공유 오브젝트에 대한 액세스가 필요하면 이 작업은 해당 오브젝트에 대한 잠금을 확보합니다. 오브젝트의 조작을 완료하면 작업이 잠금을 해제합니다.
잠금은 일반적으로 공유 오브젝트가 작성되거나 플러그인이 이 오브젝트에 처음으로 액세스할 때 작성됩니다. 즉, 공유 오브젝트에 대한 참조가 있는 코드에도 해당 잠금에 대한 참조가 있습니다. 다음과 같이 myObject에 대한 액세스를 제어하는 데 사용되는 잠금인 myLock을 작성하여 설명을 시작합니다.
... myObject = initializeImportantObject(); IJobManager jobMan = Platform.getJobManager(); myLock = jobMan.newLock(); ...
ILock에 대한 강력한 구현이 플랫폼에 의해 제공됩니다. 작업 관리자는 클라이언트가 사용하도록 이 잠금에 대한 인스턴스를 제공합니다. 이러한 잠금은 각각이 서로 잘 알고 있으므로 순환 교착 상태를 방지할 수 있습니다. (다음에 해당 명령문에 대해 자세히 다루기로 합니다.)
작업의 코드에 myObject에 대한 액세스가 필요할 때마다 먼저 작업에 대한 잠금을 확보해야 합니다. 다음 스니펫은 잠금에 대한 공통 방법을 보여 줍니다.
... // I need to manipulate myObject, so I get its lock first. try { myLock.acquire(); updateState(myObject); // manipulate the object } finally { lock.release(); } ...
acquire() 메소드는 호출 작업에 해당 잠금에 대한 독점 액세스가 부여될 수 있을 때까지 리턴되지 않습니다. 즉, 일부 다른 작업이 이미 잠금을 확보했으면 이 코드는 잠금이 사용 가능할 때까지 차단됩니다. 오브젝트에 대해 작업 중인 동안 예외가 발생할 경우 잠금을 해제할 수 있도록 잠금을 확보하고 myObject를 조작하는 코드는 try 블록에서 줄 바꾸기됩니다.
아주 단순해 보이지 않습니까? 다행히도 잠금은 사용하기가 아주 간단합니다. 또한 잠금은 재입력이 가능한데, 이것은 동일한 잠금을 여러 번 확보하는 작업에 대해 걱정할 필요가 없음을 의미합니다. 각 잠금은 특정 스레드의 확보 및 해제 계수를 보관하며, 해제 수가 확보 수와 같을 때 하나의 작업에서만 해제됩니다.
앞에서 작업 관리자가 제공하는 잠금은 각각 서로 잘 알고 있으므로 순환 교착 상태를 방지할 수 있음을 살펴 봤습니다. 어떻게 교착 상태가 발생하는지를 이해하기 위해 단순 시나리오를 살펴 보기로 합니다. "작업 A"가 "잠금 A"를 확보하고 이어서 "잠금 B"를 확보하려고 시도한다고 가정합니다. 한편 "잠금 B"는 "잠금 A"에서 대기 중인 현재 차단된 "작업 B"에서 보유합니다. 이 교착 상태 유형은 여러 작업 사이에서 잠금을 사용할 때 발생하는 기본 설계 문제를 표시합니다. 이 단순 문제는 쉽게 방지할 수 있지만 우연한 교착 상태의 발생 가능성은 설계에서 사용되는 작업 및 잠금 수가 증가할수록 늘어납니다.
다행히 플랫폼은 사용자가 교착 상태를 식별하는 데 도움이 됩니다. 작업 관리자가 교착 상태 조건을 발견하면 작업 관리자는 교착 상태 조건을 설명하는 로그에 진단 정보를 인쇄합니다. 그런 다음 차단된 작업에서 소유하는 잠금에 대한 액세스를 대기 중인 기타 작업에 일시적으로 부여하여 교착 상태를 중단합니다. 다중 잠금과 관련된 구현을 조심스럽게 테스트하고 플랫폼에서 보고하는 모든 교착 상태 조건을 수정하는 것이 중요합니다.