1

一貫性のない出力を生成する以下のコードがあります。

string text = "t1";
new Thread ( () => Console.WriteLine (text) ).Start();

//Thread.Sleep(1);

text = "t2";
new Thread ( () => Console.WriteLine (text) ).Start();

t1とt2を生成する場合もあれば、2倍のt2を生成する場合もあります。私が今考えているのはそれです。出力がdoublet2の場合、最初のスレッドでキャプチャされた変数値はt2です。これは、最後の変数割り当ての後に開始されたためです。私は正しいですか?

注:このコードは低速のマシンで実行しています。

4

5 に答える 5

3

あなたが正しい; ウィキペディアの競合状態を参照してください。

定義上、スレッドは同期的に実行されないため、コードの順序がプログラムの動作を明確に決定することを期待するべきではありません。

于 2013-02-28T16:16:56.227 に答える
1

はい、それは単純なマルチスレッドの問題です。

最初のスレッドが開始されていない間に、テキスト変数の値を変更します。次に、最初のスレッドは新しい値で始まり、ダブル't2'があります

于 2013-02-28T16:15:48.287 に答える
1

「時々それは二重のt2を生み出している」

最初のテキストの前にテキストの値が「t2」に変更されました

new Thread ( () => Console.WriteLine (text) ).Start();

実行しました

一貫性が必要な場合は、次のように変更します。

string text = "t1";
new Thread ( () => Console.WriteLine (text) ).Start();

//Thread.Sleep(1);

string text2 = "t2";
new Thread ( () => Console.WriteLine (text2) ).Start();
于 2013-02-28T16:18:01.647 に答える
1

はい、誰もが言及しているように、競合状態があります。

あなたの場合、それはほとんどの人が最初は予期しないクロージャの振る舞いを明らかにします:クロージャはその値ではなく変数をキャプチャします。この問題は、シングルスレッドの場合に簡単に示されます。

string text = "t1";
Action a1 =  () => Console.WriteLine (text);
a1(); // prints "t1"
text = "t2";
Action a2  = () => Console.WriteLine (text) ;

a1(); // prints "t2" 
a2(); 
于 2013-02-28T16:39:23.873 に答える
-1

したがって、最も簡単な方法は、変数のロックを使用することです

これにより、あるスレッドが別のスレッドによって使用されているときに変数にアクセスできなくなります。

于 2013-02-28T16:18:23.677 に答える