2009-12-11 3 views
2

동일한 데이터 집합에서 작동하는 서로 다른 개체간에 잠금을 "공유"하는 일반적인 방법이 있습니까?C# 멀티 스레딩 공유 잠금

잠금을위한 공용 개체를 갖는 것이 일반적으로 권장되지 않는다는 것을 알고 있습니다.

예를 들어, 대기열은 스레드 안전성으로 구현 될 수 있지만 다른 대기열은 여러 대기열 작업을 잠 그려면 특정 잠금이 필요할 수 있습니다. 세 번째 클래스가 있고이 동일한 Queue 인스턴스에서 여러 개의 잠긴 작업을 수행해야하는 경우 어떻게됩니까? 예를 들어

: 가 다른 클래스가 다른 스레드에서 바로 후 old 요소를 제거하는 경우

class Worker 
{ 
    private readonly L<Something> _list; 
    public Worker(L<Something> list) { _list = list; } 

    private readonly object _lock = new object(); 
    public void Replace(Something old, Something new) 
    { 
     lock (_lock) 
     { 
      if (_list.Contains(old)) 
      { 
       _list.Remove(old); 
       _list.Add(new); 
      } 
     } 
    } 
} 

를 (그냥 타이핑을 저장, L<T>는 스레드 안전 목록입니다 가정 해 봅시다) if 조건의 경우 목록에 더 이상 요소가 포함되지 않으며 _lock은 개인 개체입니다.

실제 목록 인스턴스를 고정해야합니까?

답변

8

일반적인 방법은 ICollection.SyncRoot과 같은 속성을 노출하는 것입니다. 물론 모두이 작동하려면 잠금 장치를 준수해야합니다.

이 문제를 피하고 ck가 제안한대로 작업을 캡슐화하면 훨씬 강력하고 이해하기 쉽습니다.

+0

고마워, 그건 내 질문에 대한 올바른 대답 : 자물쇠를 공유하는 일반적인 방법입니다. 나는 그 의미를 알고 있지만 내가 알지 못하는 세 번째 가능성이 있는지보기를 원했다. – Groo

9

이 목록을 속성으로 공개하지 말고 해당 속성과 상호 작용하는 메서드 만 표시하십시오. 그런 다음 한 클래스 내의 모든 잠금을 처리하고 공용 잠금 오브젝트를 처리 할 수 ​​없습니다.

+0

나는 당신의 요지를 보았습니다. 그러나이 경우 그 데이터와 상호 작용하는 모든 방법은 같은 클래스에 속해야합니다. 일련의 작업을 수행하는 다른 클래스를 가질 수 없으며 스레드로부터 안전합니다. – Groo

+0

@ 로버트 - 직접 소식을 수정할 수 있다는 것을 알고 있습니까? – Groo

+0

@Groo : Robert Grant - OK, 그는 지역의 바보입니다. – cjk

4

기술적으로 쉽게 잠금 개체를 노출 할 수 있습니다. 이 문제는 공개하지 않는 것이 바람직한 이유가 교착 상태라는 것입니다.

잠금 개체가 노출 된 경우 잠금 순서에 관계없이이 코드에서 다른 코드가 잠길 위험이 있습니다. 이것은 교착 상태로 이어질 수 있습니다.

잠금 장치가 명시 적으로 노출되지 않은 경우에도 동일한 위험이 있습니다.

최선의 방법은 암시 적으로 노출시키지 않고 암시 적으로 또는 명시 적으로 모두를 노출시키지 않는 것입니다. 다른 말로하면, 그들은 서비스를 제공하는 수업 안에 그들을 완전히 묻어 두는 것입니다. 불행히도 때로는 이것이 옵션이 아닙니다.