2009-03-19 3 views
3

이 코드를 참조하십시오 :내부에 루프가있을 때 lock 문이 작동하지 않습니까?

public class multiply 
{ 
    public Thread myThread; 
    public int Counter 
    { 
     get; 
     private set; 
    } 
    public string name 
    { 
     get; 
     private set; 
    } 

    public void RunConsolePrint() 
    { 

     lock(this) 
     { 
     RunLockCode("lock"); 
     } 


    } 

    private void RunLockCode(string lockCode) 
    { 
     Console.WriteLine("Now thread "+lockCode+" " + name + " has started"); 
     for (int i = 1; i <= Counter; i++) 
     { 
      Console.WriteLine(lockCode+" "+name + ": count has reached " + i + ": total count is " + Counter); 
     } 
     Console.WriteLine("Thread " + lockCode + " " + name + " has finished"); 
    } 
    public multiply(string pname, int pCounter) 
    { 
     name = pname; 
     Counter = pCounter; 
     myThread = new Thread(new ThreadStart(RunConsolePrint)); 
    } 

} 

을 그리고 이것은 테스트 실행 코드입니다 때문에, m2m1 시작이 실행, 또는 그 반대하기 전에 처음부터 끝까지 실행해야

static void Main(string[] args) 
    { 
     int counter = 50; 

     multiply m2 = new multiply("Second", counter); 
     multiply m1 = new multiply("First", counter); 
     m1.myThread.Start(); 
     m2.myThread.Start(); 
     Console.ReadLine(); 
    } 

내가 기대 lock 성명 그러나 내가 찾은 결과는 먼저 잠그고 두 번째 자물쇠가 함께 섞인 즉, 이와 비슷한 것입니다.

Now thread lock First has started 
Now thread lock Second has started 
lock First: Count has reached 1: total count is 50 
lock First: Count has reached 2: total count is 50 
lock Second: Count has reached 1: total count is 50 

내가 뭘 잘못 했습니까?

답변

21

코드의 각 인스턴스가 다른 개체에서 잠겨 있습니다. 모든 인스턴스간에 잠금 객체를 공유해야하며이를 정적 클래스 변수로 만듭니다.

private static object syncRoot = new object(); 
public void RunConsolePrint() 
{ 
    lock(syncRoot) 
    { 
     RunLockCode("lock"); 
    }  
} 
+0

이런 ... 당신은 빠르며, 당신 말이 맞습니다! 감사. – Graviton

+0

디자인 관점에서 볼 때 정적 변수를 잠그는 아이디어는별로 좋지 않습니다. 나는 공유 상태가 각 객체의 생성자에 전달되는 것을 선호합니다. 외부 클래스가 공유 상태에 액세스하지 못하도록하는 것이 바람직합니다. – Juliet

관련 문제