2

오늘 나는이 기능에 대한 액세스를 잠금 유효 솔루션 인 경우 궁금 해서요 코드잠금 기능 본체

이 조각
internal object UpdatePracownik(object employee) 
{ 
    lock (employee) 
    { 
     // rest of the code 
    } 

    return employee; 
} 

우연히 만났다? 속성을 대신 잠금 이런 종류의

[MethodImpl(MethodImplOptions.Synchronized)] 

를 사용하는

더 나은하지 않을까요?

+0

달성하려는 목표를 설명하는 데 도움이 될 수 있습니다. 'employee' 오브젝트의 특정 인스턴스를 잠 그거나,'UpdatePracwnik' 메소드의 모든 사용을 잠그고 자합니까? –

답변

1

글쎄요. 모든 스레드가 매개 변수로 전역 적으로 볼 수있는 동일한 객체를 전달하여이 메소드를 호출하면 모두 동일한 잠금을 볼 수 있으므로 문제가 발생하지 않습니다.

대신 각 스레드가 자체 개체를 전달하여이 메서드를 호출하면 모든 스레드가 서로 다른 잠금을 보게되므로 잠금이 유용하지 않습니다. 이 메소드가 안전한지 여부를 확인하기 위해 메소드가 호출되는 컨텍스트를 알아야합니다. 여러 스레드에 의해 실행의 원 자성을 보장하지만 당신의 목적을 위해 너무 성긴 수 있습니다

internal object UpdatePracownik(object employee) 
{ 
    lock (this) 
    { 
     // code   
    } 
} 

: 당신이 제안한 동기화 방법을 사용하여

전체 메소드 본문이 같은 lock(this) 문에 싸여 수 있습니다 일반적으로 권장하지 않습니다.

+1

나는 더 멀리 가서 'this'에 대한 잠금이 큰 노 (http://blogs.msdn.com/b/bclteam/archive/2004/01/20/60719.aspx)라고 말합니다. 문제는 컨트롤 외부의 코드가 인스턴스를 잠그고 잠재적으로 교착 상태가 발생할 수 있다는 것입니다. private 멤버 private 읽기 전용 _lock = new object(); 바람직하다. –

1

메서드를 동기화하는 데 MethodImpl 특성을 사용하면 메서드와 관련된 개체를 잠그는 것과 같습니다.

이것은 한 번에 하나의 스레드 만 메서드를 실행할 수 있지만 동일한 데이터를 사용하지 않는 한 다른 스레드를 제외 할 필요가 없음을 의미합니다.

또한 메소드가 그 자체로 동기화되었음을 의미하지만 동일한 식별자를 사용하여 다른 메소드도 잠글 수 있습니다. 예를 들어 DeletePracownik 메서드를 UpdatePracownik과 함께 동기화하면 업데이트되는 동안 하나의 개체를 삭제할 수 없습니다.

0

같은 이유로 직원의 인스턴스를 잠그는 것은 좋지 않습니다. 컨트롤 외부의 코드도 해당 인스턴스를 잠그고 교착 상태 (blogs.msdn.com/b/bclteam/archive/2004/01/20/60719.aspx)를 일으킬 수 있습니다.

private readonly object _lock = new object(); 

... 

lock (_lock) 
{ 
.. 
} 

은 또한 당신이 ReaderWriterLockSlim을 숙지해야합니다 : private 멤버를 사용하는 것이 바람직하다. 쓰기 작업이 진행중인 경우가 아니라면 특정 기능에 대한 동시 액세스를 허용 할 수 있습니다.

private readonly ReaderWriterLockSlim _rwLock = new ReaderWriterLockSlim(); 

public void ReadOp() 
{ 
    _rwLock.EnterReadLock(); //only blocks if write lock held 
    try 
    { 
     //do read op 
    } 
    finally 
    { 
     _rwLock.ExitReadLock(); 
    } 
} 

public void WriteOp() 
{ 
    _rwLock.EnterWriteLock(); //blocks until no read or write locks held 
    try 
    { 
     //do write op 
    } 
    finally 
    { 
     _rwLock.ExitWriteLock(); 
    } 
}