잠금 개체가 정적이어야하는 이유는 무엇입니까?


112

다중 스레딩에서 잠금을 위해 개인 정적 읽기 전용 개체를 사용하는 것은 매우 일반적입니다. 개인은 캡슐화를 조여 잠금 개체에 대한 진입 점을 줄이고 따라서 가장 필수적인 항목에 액세스 할 수 있음을 이해합니다.

하지만 왜 정적일까요?

private static readonly object Locker = new object();

마지막에 필드는 내 클래스 내에서만 사용되며 대신 이것을 사용할 수도 있습니다.

private readonly object Locker = new object();

다른하실 말씀 있나요?

최신 정보:

예를 들어이 코드를 붙여 넣었습니다 (예제). 나는 이것에 정적 또는 비 정적 사물함을 사용할 수 있으며 둘 다 잘 작동합니다. 아래의 답변을 고려할 때 내 사물함을 이와 같이 정의해야합니까? (미안하지만 다음 주에 인터뷰가 있고 모든 세부 사항을 알아야합니다. :)

private readonly object Locker = new object();

다음은 코드입니다.

    private int _priceA;
    private int _priceB;
    private EventWaitHandle[] _waithandle;
    private readonly IService _service;

//ctor
public ModuleAViewModel(IService service)
    {
        _service = service;
        _modelA = new ModelA();
        _waithandle = new ManualResetEvent[2];
        _waithandle[0] = new ManualResetEvent(false);
        _waithandle[1] = new ManualResetEvent(false);
        LoadDataByThread();
    }


 private void LoadDataByThread()
        {
            new Thread(() =>
                           {
                               new Thread(() =>
                               {
                                   lock (Locker)
                                   {
                                       _priceA = _service.GetPriceA();
                                   }
                                   _waithandle[0].Set();
                               }).Start();

                               new Thread(() =>
                               {
                                   lock (Locker)
                                   {
                                       _priceB = _service.GetPriceB();
                                   }
                                   _waithandle[1].Set();
                               }).Start();

                               WaitHandle.WaitAll(_waithandle);
                               PriceA = _priceA;
                               PriceB = _priceB;
                           }).Start();
        }

감사


15
내가 아는 한, 정적은 일반적으로 인스턴스와 무관하게 만드는 데 사용됩니다. "MyWorkerClass"인스턴스가 여러 개있는 경우 한 번에 하나만 주어진 데이터로 실행할 수 있습니다 (모두 공유 리소스를 사용한다고 가정).
Brad Christie

2
된다 : 편집은 중요한 세부 사항이 부족 _service하고 _waithandle위치를? 예? 공전? 다른? 즉 , 예를 들어, ... 원격 서버에 의도적으로 동기화 액세스 할 수
마크 Gravell

오른쪽, 두 번째 편집 : 예,이 끝에서 인스턴스별로 잠글 수 있습니다. 그래도 정적으로 만들 이유 가있을 있습니다. 원래 개발자가 액세스를 동기화하여 서버가이 AppDomain에서 한 번에 하나의 요청 만 받도록하려는 경우 ... 그럴 수 있습니다. , 또는 그것이 우연인지 여부.
Marc Gravell

답변:


177

"다중 스레딩에서 잠금을 위해 개인 정적 읽기 전용 개체를 사용하는 것이 매우 일반적"이 아니라 적절한 / 선택된 세분성에서 잠금을 사용하는 것이 일반적 입니다. 때때로 그것은 static. 더 자주, IMO는 그렇지 않지만 인스턴스 기반입니다.

static잠금이 표시되는 주요 시간 은 글로벌 캐시 또는 글로벌 데이터 / 싱글 톤의 지연된로드입니다. 그리고 후자의 경우 어쨌든 더 나은 방법이 있습니다.

그래서 그것은 정말로 다릅니다 : Locker당신의 시나리오에서 어떻게 사용됩니까? 자체적으로 정적 인 것을 보호하고 있습니까? 그렇다면 잠금은 정적이어야합니다. 인스턴스 기반을 보호하는 경우 IMO 잠금 인스턴스 기반이어야합니다.


24
글로벌 데이터로드를 지연시키는 더 나은 방법에 대해 자세히 설명해 주시겠습니까?
bizi

인스턴스 기반 인 여러 장소가있는 경우 여전히 스레드 안전 방식으로 액세스되는 메서드 / 변수를 제어하고 싶기 때문에 항상 정적 / 휘발성을 사용합니다. 많은 인스턴스가 동일한 리소스에 액세스 할 수 있으며이를 제어하고 싶습니다. 나도이 일을 더 잘하고 싶습니다. 당신은 훌륭한 담당자를 보유하고 있으며 귀하의 답변이 제가 채택하기에 똑같이 훌륭 할 것이라고 확신합니다. 답장 해주세요.
Andrew Simpson

82

정적 일 필요는 없습니다 . 사실 때로는 정적 일 필요가 없습니다 .

변수는 잠금에 사용하는 메서드와 동일한 범위에 있어야합니다. 메서드가 정적이면 변수는 정적이어야하고 메서드가 인스턴스 메서드이면 변수는 인스턴스 변수 여야합니다.

인스턴스 메서드에서 잠그는 데 사용되는 정적 변수는 계속 작동하지만 너무 많이 잠 깁니다. 동일한 인스턴스의 메서드뿐만 아니라 모든 인스턴스의 모든 메서드를 잠급니다.


28
"a-ha"에 대한 +1 ... 동일한 인스턴스의 메서드뿐만 아니라 모든 인스턴스의 모든 메서드를 잠급니다.
radarbob

3
@radarbob-사소한 세부 사항 : 더 많은 클라이언트가 관심을 가질 수있는 잠금 만 취하는 모든 메서드잠그지 는 않습니다 . 메서드는 잠기지 않고 뮤텍스가 사용 된 것입니다.
Erno 2014-04-09

이 답변의 문구가 오해의 소지가 있다고 생각합니다. 잠금은 메서드 범위와 관련하여 아무것도 할 필요가 없어야 합니다. 해당 메서드에서 액세스 하는 공유 데이터의 범위에만 관련되어야 합니다. 인스턴스 메소드는 공유 데이터에 액세스 할 수 없으며 (따라서 잠금이 필요하지 않음) 정적 공유 데이터에 액세스 할 수 있습니다 (따라서 정적 잠금이 필요하며 리팩토링이 대신 좋은 아이디어 일 수 있음), 정적에 대해 동일 ...
Alexei Levenkov

@AlexeiLevenkov : 데이터가 정적인지 아닌지에 따라 범위가 실제로 결정되어야한다는 것이 맞습니다.하지만 메서드의 범위도 그에 따라 결정되어야하므로 모두 함께 맞습니다. 인스턴스 데이터는 일반적으로 잠금이 필요하지 않지만 인스턴스가 스레드간에 공유되는 경우 잠금이 필요합니다.
Guffa

28

잠금의 범위와 수명은 잠 그려는 '물건'에 따라 달라집니다. 정적 잠금은 주로 정적 사물을 잠그는 데 사용됩니다.


3
사소한 세부 정보 : 잠금은 정적이 아니며 잠금을 식별하는 데 사용하는 개체는 정적입니다. 또 다른 사소한 세부 사항 : "사물"을 잠그지 않습니다.
Guffa 2014

2
예, 잘못된 "물건"을 잠그려고하면 너무 크고 강해서 언젠가는 탈출 할 수 있다고 생각합니다.
ProfK 2015

12
@Guffa 홀수의, 당신이 바르게 말했다 위의 코멘트에 : 지금은 그 말을하기 전에 1 분을보고 "당신은 그냥 일을과 복잡함을하고 있습니다", 당신이 일 :)과 복잡함을 한 것 같다
니콜라스 피터슨을
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.