2010-12-09 6 views
1

스레드로부터의 안전성을 위해 작동하지 않으며 이것은 내가 무슨 짓을 :개체 잠금은 내가 더 잘 이해하기위한 스레드 안전성을 테스트했다

내가 가지고 두 가지 방법이있다 ThreadSample라는 유형이 잠금이 일어나고있다 :

internal class ThreadTime 
    { 

     public void doSomething(string message) 
     { 
      lock (this) 
      { 
       DialogResult t = MessageBox.Show(message); 
       Thread.Sleep(2000); 
      } 
     } 

     public void anotherLife(string message) 
     { 
      MessageBox.Show("This is coming from anotherLife method and and current threadNumber is " + message); 
     } 
    } 

기본적 아이디어는 doSomething()가 호출 될 때, 그것은 전체 개체를 고정해야하고 다른 스레드가 잠금을 해제하기가 ​​기다리고 있기 때문에 다른 스레드도 anotherLife 메소드를 호출 할 수있다. 바로 아래의 코드에서 볼 수 있듯이

public partial class Form1 : Form 
{ 
    private ThreadTime time; 
    private Thread thread; 

    public Form1() 
    { 
     InitializeComponent(); 
    } 

    private void Form1_Load(object sender, EventArgs e) 
    { 
     thread = new Thread(new ThreadStart(workerThread)); 
     time = new ThreadTime(); 
    } 

    private void button1_Click(object sender, EventArgs e) 
    { 
     thread.Start(); 
     //Thread.Sleep(1000); 
     time.anotherLife("Current thread is = " + "UI Thread"); 
    } 

    private void workerThread() 
    { 
     //time.doSomething("Current thread is = " + Thread.CurrentThread.ManagedThreadId); 
     time.doSomething("Worker Thread"); 
    } 
} 

: Form가 초기화되고

, 새로운 ThreadThreadSample이 만들어

은 잠금 해제를 시뮬레이션하는 논리이다. 그런 다음 사용자가 button1을 클릭하면 스레드가 시작되고 UIThread가 도달하여 처음에 스레드로부터 안전하지 않은 anotherLife을 호출합니다.

어쨌든, 출력은 :

  • 동시에 도시 개의 메시지 박스가있다.

은 내가 기대 한 것은 새로운 스레드가 doSomething()를 호출 할 때, 그것은 anotherLife 메소드를 호출 할 수 있도록 출시 될 물체와 잠금 UIThread 대기의 잠금을 얻을 수있다.

이유를 설명 할 수 있습니까?

감사합니다.

+3

분명히 C# 일 때 자바 태그를 얻은 이유는 무엇입니까? 왜 C#에서 Java 명명 규칙을 사용하고 있습니까? –

+0

귀하의 질문을 읽는 방법, 당신은 자물쇠가 작동하는 방법에 대한 몇 가지 잘못된 생각이 들리는 것 같습니다. 객체에 대한 잠금은 동기화 할 토큰에 불과합니다. 잠금 객체 자체에는 아무런 변화가 없습니다. –

+0

Java 태그가 언어가 아닌 규칙을 참조 할 수 있습니까? –

답변

5

내가 기대했던 것은 새 스레드가 doSomething()을 호출 할 때 객체의 잠금을 가져오고 UIThread가 anotherLife 메소드를 호출 할 수 있도록 잠금이 해제 될 때까지 기다리는 것입니다. UIThread은 잠금을 기다리지 않습니다

anotherLife가 잠금을 수행하지 않기 때문에 진행 anotherLife을 허용하기 전에 발표한다. 두 스레드 모두 찾으려는 동작을 얻으려면 lock 문 (같은 개체를 잠근 상태)로 실행해야합니다. 같은 뭔가를 수정 해보십시오 :

public void anotherLife(string message) 
{ 
    lock (this) 
    { 
     MessageBox.Show("This is coming from anotherLife method and and current threadNumber is " + message); 
    } 
} 
1

음, lock(this) 또는 lock(someThing)는 잘못된 은유의 비트가 될 수 있습니다.

'to'this에는 아무 것도 수행되지 않지만 lock의 인수는 토큰으로 사용됩니다. 특정 자원에 액세스하는 모든 스레드는 동일한 토큰 (오브젝트)을 사용하여 액세스를 요청해야합니다. 그렇지 않으면 코드가 손상됩니다. 자주 도우미 개체를 사용하는 이유

:

모든 스레드가 myList을 변경하기 전에 myLock을에 잠금 경우이 제도에만 작동
private List<string> myList = ...; 
private object myLock = new object(); 

lock(myLock) 
{ 
    myList.Add("foo"); 
} 

.
List <>이 잠겨도 안전하다는 보장이 없으므로 '우수 사례'로 간주됩니다.

1

만 스레드는

당신은

private void button1_Click(object sender, EventArgs e) 
    { 
     thread.Start(); 
     //Thread.Sleep(1000); 
     time.anotherLife("Current thread is = " + "UI Thread"); 
    } 

코드를 기반으로

private void button1_Click(object sender, EventArgs e) 
    { 
     thread.Start(); 
     //Thread.Sleep(1000); 
lock(time) 
{ 
     time.anotherLife("Current thread is = " + "UI Thread"); 
} 
    } 

에, 것을 의미하면 객체에 대한 잠금을 넣어 생각 보인다 변경해야하는 잠금 장치를 관찰 개체는 다른 것으로 액세스 할 수 없습니다. 그건 사실이 아니야. 객체 잠금은 잠금이 첫 번째 잠금이 해제 될 때까지 객체에 적용되지 않을 수도 있음을 의미합니다.

코드의 두 위치에서 하나의 스레드에 액세스하고 다른 하나는 단추 이벤트에서 개체에 액세스합니다. 두 곳 모두에 자물쇠가 있어야합니다.

+0

이것은 깔끔한 설명입니다. 특히 마지막 두 번째 단락. +1 감사합니다. – Tarik

관련 문제