|
락 키워드는 주어진 객체에 대해 뮤텍스를 취하고 문장을 실행한 후 락을 해제하여 문장 블록을 임계 영역으로 표시합니다.
lock 문은 기본적으로 Monitor.Enter와 Monitor.Exit을 사용합니다. 즉, lock(this)가 실행될 때 Monitor.Enter(this)가 실행되고, Monitor.Exit(this)는 괄호 끝에서 실행됩니다. 이 문은 무슨 의미인가요? 어떤 객체에서든 메모리의 첫 부분은 모든 메서드의 주소이고, 두 번째 부분은 인덱스입니다. 그는 CLR의 SyncBlock 캐시 영역에 있는 SyncBlock을 가리켰습니다. 그게 무슨 뜻인가요? 즉, Monitor.Enter(Object)를 실행할 때 객체의 인덱스 값이 음수라면, SyncBlock 캐시에서 SyncBlock을 선택하고 그 주소를 객체 인덱스에 넣으세요. 이렇게 하면 객체로 표시된 잠금이 완료되고, 다른 스레드들은 다시 Monitor.Enter(object) 작업을 수행하려 합니다. 이 작업은 긍정적인 객체가 있는 인덱스를 받고 대기합니다. 인덱스가 음수가 될 때까지, 즉 스레드가 Monitor.Exit(object)를 사용해 인덱스를 음수로 바꿉니다. 자물쇠를 사용할 때 주의해야 할 점:
1.lock은 null 값을 잠글 수 없습니다. 객체는 null을 가리킬 수 있지만, null을 해제할 필요는 없습니다. (참고: Full Null 이해하기) 2.lock은 문자열 타입을 잠글 수 없지만, 참조 타입이기도 합니다. 문자열 유형이 CLR에 의해 "떠돌기" 되기 때문입니다 즉, 프로그램 전체에 특정 문자열의 인스턴스가 하나뿐이며, 그 객체가 모든 실행 중인 애플리케이션 도메인의 모든 스레드에서 그 텍스트를 나타냅니다. 따라서 애플리케이션 프로세스 내 어디에서든 동일한 내용을 가진 문자열에 잠금이 걸려 있는 한, 애플리케이션 내 해당 문자열의 모든 인스턴스는 잠깁니다. 따라서 지속되지 않는 사적 또는 보호된 회원은 잠그는 것이 최선입니다. 3.locklock 객체는 프로그램 블록의 메모리 경계입니다 4. 값 타입은 잠글 수 없는데, 이전 텍스트에서 빨간색으로 표시된 "객체가 해제되었다"가 있고, 값 타입은 참조 타입이 아니기 때문입니다 5.lock은 프로그램이 제어하지 않는 공개 유형이나 객체를 잠그는 것을 방지합니다. 예를 들어, 인스턴스가 공개적으로 접근 가능하다면, Lock(this)은 통제되지 않은 코드가 객체를 잠글 수 있기 때문에 문제가 될 수 있습니다. 이로 인해 두 개 이상의 스레드가 동일한 객체를 해제하기 위해 대기하는 교착 상태가 발생할 수 있습니다. 공개 데이터 유형(객체 유형이 아닌 객체)을 잠그는 것도 같은 이유로 문제를 일으킬 수 있습니다. lock(this)을 사용할 때, 임계 영역에 속하지 않는 메서드가 클래스 멤버 변수의 값을 변경할 수 있습니다
적용 시나리오: 다중 스레드 연산으로 인해 공개 변수 값에 불확실한 예외가 발생하지 않도록 방지하여 연산의 보안을 보장하는 데 자주 사용됩니다
|