10

현재 C# 응용 프로그램을 작성 중입니다. 나는 ConcurrentDictionary를 처음 사용하므로 thread의 안전성에 대해 몇 가지 질문을한다. 첫째, 이것은 내 사전입니다 :ConcurrentDictionary 사용에 관한 몇 가지 질문

/// <summary> 
    /// A dictionary of all the tasks scheduled 
    /// </summary> 
    private ConcurrentDictionary<string, ITask> tasks; 

이 클래스를 인스턴스화하여 ITask를 구현하는 모든 객체를 추적합니다. 내 설정이 멀티 스레드 환경에서 올바르게 작동하는지 확인하고 싶습니다.

ConcurrentDictionary에서 여러 스레드가 항목 수를 가져 오려면 잠금해야합니까?

사전에서 특정 키를 가져 오려면 해당 키의 개체를 가져 와서 메서드를 호출하십시오. 잠글 필요가 있습니까? 예 :

/// <summary> 
    /// Runs a specific task. 
    /// </summary> 
    /// <param name="name">Task name.</param> 
    public void Run(string name) 
    { 
     lock (this.syncObject) 
     { 
      var task = this.tasks[name] as ITask; 
      if (task != null) 
      { 
       task.Execute(); 
      } 
     } 
    } 

여러 스레드가 Run 메서드를 호출하여 ITask의 Execute 메서드를 호출 할 수 있습니다. 내 목표는 모든 스레드를 안전하고 가능한 수행 할 수있게하는 것입니다.

답변

9

방법 및 ConcurrentDictionary 특성 스스로가 완전히 스레드 안전된다

http://msdn.microsoft.com/en-us/library/dd287191.aspx

동시에 다수의 스레드에 의해 액세스 될 수있는 키 - 값 쌍의 스레드 안전 컬렉션을 나타낸다.

이것은 Count 속성을 포함

카운트가 스냅 의미를 가지며 카운트 액세스 때 순간에 ConcurrentDictionary의 항목 수를 나타낸다.

그러나하지는 사전 내부에 개최 된 객체 자체가 스레드에 안전하다는 것을 의미한다. 즉, 두 개의 스레드가 동일한 Task 개체에 액세스하는 것을 중지하고이 스레드에서 Execute 메서드를 실행하려고 시도하는 것이 아닙니다.Execute을 실행할 때, 그때는 Execute 방법에 대한 각각의 작업에 직렬화 (잠금) 액세스를 좋아 Task 내부 잠금 개체를 갖는 잠금 좋을 것 경우

public class Task 
{ 
    private object _locker = new object(); 

    public void Execute() 
    { 
     lock (_locker) { 
      // code here 
     } 
    } 
} 

이 적어도 모든 개인 작업 아무튼 보장 Execute을 실행중인 여러 스레드가 없습니다. 나는 이것이 당신이 질문의 문맥과 클래스와 메소드의 이름에서 온 것임을 짐작하고있다.

+0

은'.count' 속성 쓰레드 안전합니까? 또는'.Count()'메쏘드? 그 차이점은 무엇입니까? – Zapnologica

2

ConcurrentDictionary의 모든 메소드는 여러 스레드에서 호출하는 것이 안전합니다.

다른 개체/여러 개체에 동시에 액세스하려면 잠금을 사용해야하므로 프로그램의 다른 부분에 동기화가 필요하지 않습니다.

e.e. 샘플 코드는 작업 검색 및 실행 모두에 대해 잠금을 유지합니다. 원자 적으로 다중 객체에 액세스하기위한 잠금 예제를 보여줍니다.

사이드 노트 : task.Execute()에 대한 잠금을 검토하면 다른 스레드가 동시에 작업을 실행할 수 없으므로 검토해야합니다. 그것은 당신이 달성하기를 원하는 것이지만,이 경우에는 ConcurrentDictionary를 사용하면 과도 할 수 있습니다.