メソッドをスレッドセーフにするにはどうすればいいでしょうか? ルールは何ですか? 質問する

メソッドをスレッドセーフにするにはどうすればいいでしょうか? ルールは何ですか? 質問する

メソッドをスレッドセーフにする全体的なルールやガイドラインはありますか? おそらく一回限りの状況が 100 万もあることは理解していますが、一般的にはどうでしょうか? こんなに単純なのでしょうか?

  1. メソッドがローカル変数にのみアクセスする場合、スレッドセーフです。

そうですか?それは静的メソッドにも当てはまりますか?

@Cybis が提供した回答の 1 つは次の通りです。

各スレッドは独自のスタックを取得するため、ローカル変数はスレッド間で共有できません。

静的メソッドでも同様でしょうか?

メソッドに参照オブジェクトが渡されると、スレッド セーフティが損なわれるのでしょうか。私は調査を行っており、特定のケースについては多くの情報が出回っていますが、いくつかのルールを使用して、メソッドがスレッド セーフであることを確認するためのガイドラインを定義できればと考えています。

したがって、私の最終的な質問は、「スレッドセーフなメソッドを定義するルールの短いリストはありますか? ある場合、それは何ですか?」です。

編集
ここでは多くの良い点が指摘されています。この質問に対する本当の答えは、「スレッドの安全性を保証する簡単なルールはない」だと思います。いいですね。しかし一般的に受け入れられた回答は、簡潔で良い要約を提供していると思います。例外は常に存在します。それでいいのです。それでいいのです。

ベストアンサー1

メソッド (インスタンスまたは静的) がそのメソッド内でスコープされた変数のみを参照する場合、各スレッドが独自のスタックを持つため、スレッドセーフです。

この場合、複数のスレッドがThreadSafeMethod問題なく同時に呼び出すことができます。

public class Thing
{
    public int ThreadSafeMethod(string parameter1)
    {
        int number; // each thread will have its own variable for number.
        number = parameter1.Length;
        return number;
    }
}

メソッドがローカル スコープの変数のみを参照する他のクラス メソッドを呼び出す場合も同様です。

public class Thing
{
    public int ThreadSafeMethod(string parameter1)
    {
        int number;
        number = this.GetLength(parameter1);
        return number;
    }

    private int GetLength(string value)
    {
        int length = value.Length;
        return length;
    }
}

メソッドが (オブジェクトの状態) プロパティまたはフィールド (インスタンスまたは静的) にアクセスする場合は、値が別のスレッドによって変更されないようにロックを使用する必要があります。

public class Thing
{
    private string someValue; // all threads will read and write to this same field value

    public int NonThreadSafeMethod(string parameter1)
    {
        this.someValue = parameter1;

        int number;

        // Since access to someValue is not synchronised by the class, a separate thread
        // could have changed its value between this thread setting its value at the start 
        // of the method and this line reading its value.
        number = this.someValue.Length;
        return number;
    }
}

メソッドに渡される、構造体でも不変でもないパラメータは、メソッドのスコープ外の別のスレッドによって変更される可能性があることに注意してください。

適切な同時実行性を確保するには、ロックを使用する必要があります。

詳細についてはロック ステートメント C# リファレンスそしてリードライターロックスリム

ロック一度に 1 つの機能を提供するのに最も役立ちますが、
ReadWriterLockSlim複数のリーダーと単一のライターが必要な場合に便利です。

おすすめ記事