2009-04-08 4 views
1

나는 멀티 스레드 응용 프로그램에서 일반 사전을 가지고 있습니다. 자물쇠를 구현하는 속성을 만들었습니다. 지금 내가 쓰는 경우스레딩 : 일반 사전에 잠금

static object myLock=new object(); 
Dictionary<key,SomeRef> dict=new Dictionary<key,SomeRef>(); 

public Dictionary<key,SomeRef> MyDict{ 
     get{ 
     lock(myLock){ 
     return dict; 
     } 
    } 
} 

CODE # 1

MyDict.TryGetValue 

또는 CODE # 2

var result=MyDict.Values; 
foreach(var item in result){ 
//read value into some other variable 
} 

그래서 잠시 메신저 runnig 코드 1 또는 2와 같은 시간에 다른 스레드 시도하는 경우 ..clear dict와 같은 사전에 쓰기 작업을하거나 새 항목을 추가하십시오. 그런 다음이 솔루션은 스레드로부터 안전합니다 (속성 사용). 그렇지 않다면 을 수행하십시오. 다른 방법이 있습니다.

필자가 쓰기 작업을 할 때 속성 작성자 키 엑소스트리스트를 통해 사전을 참조하거나 키를 작성하지 않고 값을 할당 할 수 있습니다. (따라서 재산에서 세터를 사용하지 않습니다.)

답변

4

아니요, 이것은 스레드 안전하지 않습니다.

자물쇠는 사전의 내부 (사전) 인스턴스에 대한 참조를 얻는 것만으로 고정됩니다. 사용자가 사전에 추가하거나 사전에서 읽으려고하면 잠금되지 않습니다.

스레드 세이프 액세스를 제공해야하는 경우 사전을 비공개로 유지하고 사전에/설정 값을 추가/가져 오기위한 고유 한 방법을 만드는 것이 좋습니다. 이 방법을 사용하면 자물쇠를 설치하여 필요한 수준으로 보호 할 수 있습니다.


는 다음과 같이 표시됩니다

public bool TryGetValue(key thekey, out SomeRef result) 
{ 
    lock(myLock) { return this.dict.TryGetValue(thekey, out result); } 
} 
public void Add(key thekey, SomeRef value) 
{ 
    lock(myLock) { this.dict.Add(thekey, value) } 
} 
// etc for each method you need to implement... 

여기 아이디어는 고객이 직접 클래스를 사용한다는 것입니다, 당신의 클래스는 동기화를 처리합니다. 값 (예 : foreach 문)을 반복 할 것으로 예상되는 경우 목록에 값을 복사하여 반환할지 또는 열거자를 직접 제공할지 (IEnumerator<SomeRef> GetValues()) 등을 결정할 수 있습니다.

3

아니요,이 locked의 유일한 코드가 검색 코드이므로 안전하지 않습니다. 당신이해야 할 것은

lock(MyDict) 
{ 
    if(MyDict.TryGetValue()... 
} 

lock(MyDict) 
{ 
    foreach(var item in MyDict.Values) ... 
} 

기본적인 아이디어는 잠금() 블록 내에서 작업 코드를 둘러싸입니다.

+0

아담 감사합니다. 차이점은 무엇입니까 lock (MyDict) {if (MyDict.TryGetValue() ...} 및 lock (MyLock) {if (MyDict.TryGetValue() ...} –

+0

유일한 차이점은 잠금 개체입니다. 사전 (또는 다른 리소스 관련 개체)을 잠그는 것은 관례입니다. 동일한 동기화 개체를 사용하는 한 괜찮습니다. –

2

구현이 스레드 안전성을 보장하지 않습니다. 스레드 안전성을 유지하려면 동시 읽기/쓰기가 모두 잠금에 의해 보호되어야합니다. 내부 사전에 대한 참조를 전달하면 리소스에 액세스하는 사람을 제어하기가 매우 어려워 져서 호출자가 동일한 잠금을 사용할 것이라고 보장 할 수 없습니다.

좋은 접근 방법은 액세스를 동기화하려는 리소스가 사용자의 유형에 완전히 캡슐화되어 있는지 확인하는 것입니다. 이렇게하면 스레드 안전성을 이해하고 추론하는 것이 훨씬 쉬워집니다.