C#에서 lock 사용법 자세히 보기
lock 키워드는 코드 블록이 실행되고 다른 라인이 끊기지 않도록 하는 데 사용됩니다.이것은 코드 블록이 실행되는 동안 주어진 대상에게 상호 배척 자물쇠를 가져오는 것을 통해 이루어진 것이다.
먼저 실행 과정을 살펴보고 코드의 예는 다음과 같다.
lock 문장은 주어진 대상의 상호 배척 자물쇠를 가져오고 문장을 실행한 다음 자물쇠를 놓는 데 사용됩니다.lock-statement:(lock 명령문:)
lock(expression) embedded-statement(lock ( ) )
lock 문장의 표현식은 인용 형식의 값을 표시해야 합니다.lock 문장의 표현식에 대해 스텔스 컨테이너 변환을 영원히 실행하지 않기 때문에, 이 표현식이 값 형식의 값을 표시하면 컴파일할 때 오류가 발생할 수 있습니다.
다음 형식의 lock 문:
lock (x) ...
(그중 x는 인용 유형의 표현식) 완전히 같은 효과
system.threading.monitor.enter(x);
try {
...
}
finally {
system.threading.monitor.exit(x);
}
다른 것은 단지 실제 실행 중 x는 한 번만 계산할 뿐이다.
상호 배척 자물쇠가 점용되었을 때, 같은 라인에서 실행된 코드는 이 자물쇠를 가져오고 방출할 수 있습니다.그러나 다른 라인에서 실행되는 코드는 이 자물쇠가 풀리기 전에는 얻을 수 없습니다.
하나의 종류의 시스템.type 대상은 이 종류의 정적 방법에 대한 상호 배척 자물쇠로 편리하게 사용할 수 있습니다.예를 들면 다음과 같습니다.
class cache
{
public static void add(object x) {
lock (typeof(cache)) {
...
}
}
public static void remove(object x) {
lock (typeof(cache)) {
...
}
}
}
가령 라인 a가 먼저 실행한다고 가정하면 라인 b는 좀 느리다.루틴 a는 lock 문장에 실행하여obj가 상호 배제 자물쇠를 신청했는지 판단하고 판단 근거는 각각 존재하는 자물쇠와object를 진행하는 것이다.referenceequals 비교 (여기 확인되지 않음) 가 존재하지 않으면 새로운 호환 자물쇠를 신청합니다. 이 때 라인 a가lock에 들어갑니다.
이 때 루틴 b가 시작되었고 루틴 a가 lock의 코드를 실행하지 않았다고 가정합니다.루틴 b가 lock 문장에 실행되고obj가 상호 배척 자물쇠를 신청했는지 확인하여 기다립니다.루틴 a가 실행될 때까지 상호 배척 자물쇠를 풀어야 루틴 b가 새로운 상호 배척 자물쇠를 신청하고 lock 안의 코드를 실행할 수 있습니다.
다음은 lock, 어떤 대상을 말해야 할지.
왜 lock 값 형식, 예를 들어 lock(1)을 사용할 수 없습니까?lock 본질적으로 모니터.enter,monitor.enter는 값 형식을 상자에 넣을 것입니다. 매번 lock는 포장 후의 대상입니다.lock는 사실 컴파일러와 유사한 문법 설탕이기 때문에 컴파일러는 lock 값의 형식을 직접 제한할 수 없습니다.
만 걸음 물러서서 컴파일러가 lock(1)을 허락해도 Object.referenceequals(1,1)는 항상false(포장할 때마다 대상이 다르기 때문)로 되돌아온다. 즉, 매번 호환 자물쇠를 신청하지 않은 것으로 판단되므로 같은 시간에 다른 라인은 안에 있는 코드에 접근할 수 있고 동기화 효과에 도달하지 못한다.같은 논리의 lock(object) 1도 안 된다.
그럼 lock ("xxx") 문자열은요?msdn의 원어:
문자열을 잠그는 것은 특히 위험합니다. 문자열이 공공 언어 실행 라이브러리 (clr) 에 의해 '임시' 되기 때문입니다.이것은 모든 프로그램에서 주어진 문자열이 하나의 실례만 있다는 것을 의미한다. 바로 이 대상은 모든 실행 프로그램 영역의 모든 라인에서 이 텍스트를 나타낸다.따라서 프로그램 프로세스의 어느 위치에서든 같은 내용을 가진 문자열에 자물쇠를 설치하면 프로그램의 이 문자열의 모든 실례를 잠금합니다.
일반적으로 퍼블릭 형식을 잠그거나 프로그램의 제어를 받지 않는 대상을 잠그는 실례를 피하는 것이 좋습니다.예를 들어 이 실례가 공개적으로 접근할 수 있다면 lock(this)에 문제가 있을 수 있습니다. 제어되지 않은 코드도 이 대상을 잠글 수 있기 때문입니다.이것은 두 개 이상의 라인이 같은 대상을 방출하기를 기다리는 것을 초래할 수 있다.같은 이유로 공공 데이터 형식을 잠그는 것도 문제가 될 수 있다.그리고 lock(this)는 현재 대상에만 유효하며 여러 대상 사이에 동기화 효과가 나타나지 않습니다.
lock (typeof (class) 는 잠금 문자열과 같이 범위가 너무 넓습니다.
일부 시스템 클래스는 잠긴 구성원을 제공합니다.예를 들어, array 유형은 syncroot를 제공합니다.많은 집합 형식도syncroot를 제공합니다.
사용자 정의 클래스는 개인적인 읽기 전용 정적 대상을 추천합니다. 예를 들어 다음과 같습니다.
private static readonly object obj = new object();
왜 읽기만 하는 걸까요?이 때 lock 코드 세그먼트에서obj의 값을 바꾸면 다른 스레드는 서로 잠금되어 있기 때문에 막힘이 없다
대상이 바뀌었어요,object.referenceequals는false를 되돌려줍니다.
이 문서가 C# 프로그램 설계에 도움이 되었으면 합니다.
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.