ローカル変数は、スレッドの安全性に問題はありません、ありがとうございました。スレッドの安全性は、複数のスレッド間で共有状態が存在する場合に問題になります。この関数では、文字列、整数、小数などのプリミティブ型のデフォルト値であるBy Valueを渡すので、共有状態が存在しないためスレッドの安全性は問題になりません。一方、オブジェクトはReferenceによって渡され、スレッドの安全性が問題になる可能性があります。
これは典型的な例です。 _unsafe変数を100回インクリメントする100のスレッドがあるため、_unsafeの値は10000にする必要がありますが、プログラムを実行するときにはそうでない可能性があります。これは、計算を実行する1つのスレッドによって値が読み取られ、計算が実行されている間に変数の値が別のスレッドによって増分されるためです。これは競合状態と呼ばれ、避けるべきことです。ここであなたが知る必要があるすべてのトピックをカバーするスレッディングに関する素晴らしい電子ブックがあります。ここ
http://www.albahari.com/threading/
public class TestThreading(){
private static int _unsafe = 0;
public static void main(string[] args){
for(int i =0; i<100;i++){
ThreadPool.QueueUserWorkItem(PerformIncrement);
}
}
public static void PerformIncrement(){
for(int i=0;i <100;i++){
_unsafe++;
}
}
}
オブジェクトを使用して別の安全でない例です。データの同じ部分に取り組んで複数のスレッドがあるので、これはありません、パラメータを割り当てる必要がない
public class TestThreading2(){
public int unsafe = 0;
public static void main(string[] args){
TestThreading2 objectUnsafe = new TestThreading2();
for(int i=0;i <100;i++){
Thread t = new Thread (PerformIncrement);
t.Start (objectUnsafe);
}
}
public static void PerformIncrement(object referenceParameter){
var objectReference = (TestThreading2) referenceParameter;
for(int i=0;i <100;i++){
objectReference.unsafe++;
}
}
}
確かに 'string'オブジェクトは不変ですので、最初のバージョンは安全ですか? – James
こんにちは。あなたは不変のことを説明できますか?私は定義を見て、それは変更することはできないと言います。したがって、この関数に呼び出しが行われたときはいつでも、その呼び出しのオブジェクトが作成され、関数が正しく実行されるまで保持されます。だから、すべての呼び出しはその価値を維持していて、スレッドセーフなのでしょうか?一度に100回起こったとしても。 – MonsterMMORPG
そうだと思います。しかし、私は確信が持てないので、これを答えとして掲示していません。うまくいけば誰かが明らかにすることができます。 :) – James