잠금 장치 (objlocker)가 해당 객체 스레드를 안전하게 넓게 만들까요? 그리고 정적 멤버는 자동으로 스레드 스레드가 안전합니까?
-
07-07-2019 - |
문제
객체를 잠그면 해당 객체가 전체 응용 프로그램 전체에 잠겨 있습니까?
예를 들어, 간단한 섹션 19.6.1 "스레드 안전 및 .NET 프레임 워크 유형"에서 C# 3.0 의이 스 니펫 : :
static void AddItems( )
{
for (int i = 0; i < 100; i++)
lock (list)
list.Add ("Item " + list.Count);
string[] items;
lock (list) items = list.ToArray( );
foreach (string s in items) Console.WriteLine (s);
}
첫 번째 잠금 장치 :
lock (list)
list.Add ("Item " + list.Count);
다른 스레드가 액세스하는 것을 방지합니다.
lock (list) items = list.ToArray( );
아니면 동시에 실행할 수 있습니까?
CLR이 자동으로 정적 메서드 스레드를 안전하게 만들까요? 아니면 개발자에게 달려 있습니까?
고마워요, 존
해결책
class UsefulStuff {
object _TheLock = new object { };
public void UsefulThingNumberOne() {
lock(_TheLock) {
//CodeBlockA
}
}
public void UsefulThingNumberTwo() {
lock(_TheLock) {
//CodeBlockB
}
}
}
CodeBlockA
그리고 CodeBlockB
동일한 객체 인스턴스에 모두 잠겨 있기 때문에 다른 스레드에서 동시에 실행하는 것이 방지됩니다. _TheLock
.
방법 _TheLock
그 자체는 완전히 영향을받지 않습니다.
다른 팁
주목해야 할 또 다른 점은 정적 생성자가 런타임에 의해 스레드 사프 방식으로 실행된다는 것입니다. 싱글 톤을 만들고 다음과 같이 선언하는 경우
public class Foo
{
private static Foo instance = new Foo();
public static Foo Instance
{
get { return instance; }
}
}
그러면 threadSafe가 될 것입니다. 그러나 당신은 새로운 foo를 인스턴스화한다면 내부에 인스턴스 getter, 그러면 나만의 스레드 안전을 작성해야합니다 (즉, 객체 잠금).
CLR은 자동으로 정적 메소드 스레드-안전을 만들지 않습니다. 당신은 직접해야합니다.
잠금 (목록)은 해당 객체를 잠금으로 사용하므로 다른 스레드가 잠금 (목록)을 사용하여 다른 스레드에 도달하면 (동일한 '목록'객체와 함께) 다른 스레드가 잠금을 출시 할 때까지 차단됩니다.
명확하게 말하면, 잠금 (foo)은 "foo 객체를 잠금"하지 않고 오히려 foo 객체와 관련된 잠금 장치를 얻습니다. 현재 스레드가 잠금을 얻었습니다.