lock (new object ()) —화물 컬트 또는 미친 "언어 특수 사례"?


87

컨설턴트가 작성한 일부 코드를 검토 중이며 이미 수십 개의 위험 신호가 나타 났지만 다음 스 니펫에 머리를 감쌀 수는 없습니다.

private void foo()
{
    if (InvokeRequired)
    {
        lock (new object())
        {
            if (m_bar!= null)
                Invoke(new fooDelegate(foo), new object[] { });
        }
    }
    else
    {
        if(OnBazChanged != null)
            OnBazChanged();
    }
}

여기서 lock (new object ())은 무엇입니까? 항상 다른 객체를 잠그기 때문에 아무 효과가 없어야하지만 이러한 유형의 잠금은 복사 및 붙여 넣기가 아닌 부분에서도 코드 전체에서 지속됩니다. 이것은 내가 모르는 것으로 컴파일 된 C # 언어의 특별한 경우입니까, 아니면 프로그래머가 얼마 전에 작동했던화물 컬트를 채택한 것일까 요?


19
나는 그들이 매우 혼란 스럽다고 생각합니다. 그들은 아마도가 new object()필드에 저장된 곳을 보았을 것이고 그 필드가 lock()명령문 에 사용되었으며 인라인하지 않는 것이 더 낫다는 것을 알지 못했습니다.
Damien_The_Unbeliever

21
그 "컨설턴트"는 몇 가지 설명을하고 있습니다 ... 당신은 틀린 것이 아닙니다 : 그 lock코드는 완전히 쓸모가 없습니다
Marc Gravell

12
@Baboon : 당신은 리팩토링을 할 수있는 일 ...하지 않은 경우에만

2
또한 이것이 WinForms라면 왜 거기에 잠금이 있어야하는지 알 수 없습니다.
Drew Noakes

7
이를 제거한 다음 100 % 코드 커버리지 테스트 스위트를 다시 실행하십시오. 그게 뭔데? 이전 컨설턴트가 만들지 않았나요?
Spacedman 2012-08-20

답변:


82

이것을 본 사람이라면 놀라지 않을 것입니다.

private readonly object lockObj = new object();

private void MyMethod()
{
    lock(lockObj)
    {
        // do amazing stuff, so amazing it can only run once at a time
        // e.g. comands on the Mars Rover, or programs on iOS pre 4 / 5 ??
    }
}

줄 수를 줄일 수 있다고 생각했습니다.

그게 사실이라면 나는 매우 걱정할 것입니다 ...


4
그는 "newObject ()"라는 메서드를 보았고이 메서드는 싱글 톤 인스턴스를 반환했지만 "이봐, C #에 키워드가 없습니까?"라고 말했습니다.
Amiram Korach

9
실제로 무슨 일이 일어나고 있는지 효과적으로 이해하지 못하는 리팩토링 작업처럼 들립니다.
Aphelion 2012-08-20

1
@OrangeDog : 안타깝게도 제가 회사에 입사하기 전에 관련 코드가 작성 되었기 때문에 불가능합니다. 이제 변경할 사항이 있으므로 경영진에게 코드를 수정하도록 설득 할 수 있습니다. 그렇지 않으면 나는 어떤 불안정성에 대해서도 책임을지지 않을 것입니다. (마지막으로 만지는 것은 비난 할 것입니다) ...

2
@Ibruder 더 높은 우선 순위는 경영진에게 버전 제어, 자동화 된 테스트 및 검토 시스템이 필요하다는 것을 설득하는 것입니다. 마지막으로 만지는 사람이 탓할 사람이라면 일하기 좋은 회사처럼 들리지 않습니다.
OrangeDog

1
나는 명백하게 깨진 잠금에 대해별로 신경 쓰지 않습니다. 다른 모든 사람들은 이미 지적했지만 '또는 iOS 4/5 이전의 프로그램'에 대해서만 +1합니다. <g>
Martin James

15

다음 은 비슷한 질문과 답변입니다.

잠금은 상호 배제를 보장합니다. 하나 이상의 스레드가 동시에 잠금을 유지할 수 없습니다. 잠금은 특정 개체 인스턴스로 식별됩니다. 매번 잠글 새 객체를 만들고 다른 스레드에게 정확히 동일한 객체 인스턴스를 잠그도록 알릴 방법이 없습니다. 따라서 잠금은 쓸모가 없습니다.


2

아마도 쓸모가 없을 것입니다. 그러나 기억 장벽을 만들 수있는 기회가 없습니다. C #이 잠금 제거를 수행하는지 또는 잠금의 순서 의미를 보존하는지 여부는 확실하지 않습니다.


몇 년 전 이었지만, 어떤 사람들은 완전히 무시했다는이 명백한 사실을 진술 한 것에 대해 당신은 전적으로 +1을받을 자격이 있습니다. 예를 들어 유니버설 Windows 플랫폼에는 MemoryBarrier () 메서드가 없으며 Interlocked.CompareExchange 및 lock (new Object ())을 사용하는 마법이 일부 문제를 처리하는 유일한 방법이됩니다.
Sergey.quixoticaxis.Ivanov

나는 C #이 이것을 허용한다는 것을 몰랐습니다. 지적 해주셔서 감사합니다.
모두
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.