2013-01-08 3 views
1
public void Remove(T item) 
{ 
    locker.EnterWriteLock();   
    try 
    { 
     list.Remove(item); 
    } 
} 

위의 내용은 인스턴스 클래스에 대한 방법입니다. 인스턴스가 myObject이라고합시다. 위의 조각에 관해서는, 제 질문은 이것입니다 :메서드 매개 변수가 스레드로부터 안전합니까?

스레드 한 전화 myObject.Remove(A).
스레드 하나가 locker.EnterWriteLock()을 실행합니다.

두 건의 호출 myObject.Remove(B)을 처리하십시오.

스레드가 try 블록에 들어가고 list.Remove()을 실행합니다.

이 시점에서 item의 값은 무엇입니까? 즉 list.Remove()이 매개 변수로 A 또는 B와 함께 호출 될 것입니까?

+2

'locker' 변수의 유형은 무엇입니까? –

+0

ReaderWriterLockSlim – Sam

+0

이 질문은 디버깅과 확인을 통해 쉽게 대답 할 수있었습니다. 당신이 알아 낸 대답에 대한 _why_의 질문은 더 좋았을 것입니다. –

답변

3

각 스레드는 자체 호출 스택을 가지며 메서드 인수는 해당 스택에 저장됩니다. 스택은 스레드간에 공유되지 않습니다.

스레드의 스택에는 Remove이 호출되고 "A"또는 값 또는 참조 유형에 따라 "A"에 대한 참조가 포함되어 있음을 나타내는 행이 있습니다.

스레드 2가 메서드에 들어갈 때 항목 "B"가있는 Remove의 시작을 나타내는 줄이있는 자체 호출 스택 (스레드 2가 실행되는 동안 스레드 1의 스택은 사용되지 않음)이 있습니다. 그런 다음 해당 스레드가 일시 중단되고 호출 스택이 사용되지 않으며 스레드 1로 돌아갑니다. 여기서 항목 "A"는 호출 스택에있는 것입니다.

미래의 어느 시점에서 스레드 2가 다시 활성화되고 호출 스택에 항목 "B"가 표시됩니다.

+0

А 작은 수정,'... 인수가 그 스택에 저장 됨. ' –

+0

예,'Remove' 정렬은'Remove'의 새로운 "인스턴스"를 만듭니다. –

0

여기에 잠겨 야 할 내용은 list 변수입니다. Remove 메서드를 호출하고이 list 변수가 List<T>과 같이 스레드로부터 안전하지 않은 형식 인 경우 (예 : myObject의 동일한 인스턴스에서이 메서드를 동시에 호출하면 문제가 발생할 수 있습니다. 귀하의 list 필드 수명). 메서드의 인수에 관해서는 메서드의 컨텍스트 내에서 스레드 안전성에 대해 이야기하는 것이 어렵습니다.

+0

알기. 내 질문은 - 목록에서 Remove라고 실제로 호출 할 때 A 또는 B로 호출 할 것인가? – Sam

+0

우리는 '사물함'의 범위가 무엇인지 알려주지 않았다는 것을 감안할 때 우리는 이것에 대해 정말로 논평 할 수 없습니다. 그는 적절한 범위에서 잠글 수도 있고 그렇지 않을 수도 있지만, 이는 그의 질문과는 관련이 없습니다. 그것은 그것보다 훨씬 기본입니다. – Servy

+0

매개 변수의 값이 무엇이든간에이 매개 변수를 호출합니다. 예를 들어 A로 메소드를 호출하면 A가 remove 메소드로 전달됩니다. 메서드 인수는 스택에 있습니다. –

0

.Net은 매개 변수에 상속 잠금을 제공하지 않습니다. 그러나 list.Remove(item)item (표준 System.Collections 또는 System.Collections.Generic 구현이라고 가정)을 수정하지 않고 다른 인수로 동일한 메소드를 두 번 호출하면 item (각 메소드 호출에 하나씩)의 사본이 하나가 아니라 두 개가 생성됩니다.

대신 대부분의 클래스의 인스턴스 메서드가 스레드로부터 안전하다는 보장이 없으므로 목록을 잠급니다.

0

스레드 2 실행 스레드 1 locker.EnterWriteLock();에서 기다리고있을 것입니다 locker.ExitWriteLock();

그래서 스레드 2가 매개 변수 item 걱정되면 그냥 통과 있는지 확인, 스레드 1 호 locker.ExitWriteLock();

전에 list에 액세스 할 수 없습니다 스택 및 각 스레드는 자체 스레드를 가지고 있으므로 item은 실제로 다른 스레드가 "대체"할 수 없습니다.

따라서 스레드 1이 locker.EnterWriteLock(); 스레드 2, AB 전에 제거됩니다.

1

메서드 인수는 메서드를 호출하는 스레드 스택에 할당됩니다. 따라서 모든 스레드는 고유 한 인수를 가지며 서로 영향을주지 않습니다.

0

item의 값은 A 매개 변수의 값입니다.

locker.ExitWriteLock이 실행되면 한 번만 스레드가 스레드를 사용할 수있게됩니다.

관련 문제