2011-10-30 7 views
1

スレッドセーフであるためには、関数のパラメータをローカル変数に代入する必要があります。受信したパラメータをasp.net 4.0のpublic static関数でローカルパラメータに代入する必要がありますか?

public static bool CheckEmailExist_1(string srEmail) 
{ 
//Do some stuff with using srEmail 
} 

public static bool CheckEmailExist_2(string Email) 
{ 
string srEmail=Email; 
//Do some stuff with using srEmail 
} 

これらの2つの関数が評価されたときに、スレッドセーフな違いはありますか?私は例えば、CheckEmailExist_1が100種類の同時通話をもちろん、異なる電子メールパラメータを持っていると言うことができます。それは操作の中の機能中に問題を引き起こすでしょうか? #4.0 C

、asp.net 4.0

+0

確かに 'string'オブジェクトは不変ですので、最初のバージョンは安全ですか? – James

+0

こんにちは。あなたは不変のことを説明できますか?私は定義を見て、それは変更することはできないと言います。したがって、この関数に呼び出しが行われたときはいつでも、その呼び出しのオブジェクトが作成され、関数が正しく実行されるまで保持されます。だから、すべての呼び出しはその価値を維持していて、スレッドセーフなのでしょうか?一度に100回起こったとしても。 – MonsterMMORPG

+0

そうだと思います。しかし、私は確信が持てないので、これを答えとして掲示していません。うまくいけば誰かが明らかにすることができます。 :) – James

答えて

1

ローカル変数は、スレッドの安全性に問題はありません、ありがとうございました。スレッドの安全性は、複数のスレッド間で共有状態が存在する場合に問題になります。この関数では、文字列、整数、小数などのプリミティブ型のデフォルト値である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++; 
     } 
    } 
} 
+0

関数呼び出しによって受け取られているオブジェクトは常にスレッドセーフなのですか?この例では電子メールです – MonsterMMORPG

+0

ValueとReferenceタイプを含むように編集しました –

0

(この場合には、それは「安全でない」クラス変数です)前の例と同じ問題を抱えています静的メソッドの。

関連する問題