2009-03-19 10 views
3

このコードを参照してください:私はのためm2は、m1実行を開始し、またはその逆の前に最初から最後まで実行しなければならないことを期待するループステートメントが内部にある場合、ロックステートメントは機能しませんか?

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(); 
    } 

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)); 
    } 

} 

そして、これは、テスト実行コードです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

関連する問題