5

複数のスレッドがget/set関数を介してプロパティ/フィールドにアクセスする場合、一般的にゲッターとセッターをロックする必要がありますか?

例えば:

オブジェクトの値を定期的に取得するタイマーがあります。そして、この値を定期的に更新するプロセス。

public class Task : IProgressProvider
{
    ...
    public Progress GetProgress()
    {
        // should i lock here?
        return _progress;
    }

    public SetProgress(Progress progress)
    {
        // and lock here?
        _progress = progress;
    }

    public void Execute()
    {
        // ...
        SetProgress(new Progress(10));
        // ...
        SetProgress(new Progress(50));
        // ...
        SetProgress(new Progress(100));
    }
}

public class ProgressReporter
{
    public ProgressReporter()
    {
        _timer = new Timer();
        _timer.Elapsed += Elapsed;
        // ...
    }

    // ...

    public void Elapsed(...)
    {
        var progress = _task.GetProgress();
        // ...
    }
}

もう一度質問:

  • GetProgress および SetProgress 関数をロックする必要があります。
  • はいの場合、なぜですか?
  • この場合、揮発性が必要です (1 つまたは複数のプロセッサ コアを想定)
  • 「単純」に保つために、Progress のプロパティ/フィールドが読み取り専用であると仮定します。編集: += などはアトミック操作ではなく、適切な処理 (fe ロック) が必要であることを知っています。

変数 _progress の設定と読み取りはアトミック操作だと思います。GetProgress が最新の値を取得することは重要ではありません。今度は GetProgress の次の呼び出しでそれを取得します。

4

3 に答える 3

4

が参照型の場合_progress、その値の読み取りと書き込み (参照の変更) は実際にはアトミック操作であるため、例の特定のコードをロックする必要はありません。しかし、setter または getter で複数のフィールドを変更したことがある場合、またはフィールドがアトミックな読み取り/書き込みを行うタイプ (double など) でない場合は、ロックする必要があります。

複数のスレッドがいつでも同じ値を監視できるようにする場合は、実際に追加のロックが必要になります。あるスレッドが 1 つの値を読み取り、別のスレッドが別の値を読み取れるかどうか (その間で変更されたため) を気にしない場合は、ロックは実際には必要ないように思われます。

確かに揮発性にします。volatileまさにそのためです。少なくとも、最適化コンパイラが値をキャッシュしてはならないときにキャッシュするのを防ぎます (そのようなことを行う場合)。

要約すると、必要な使用法のために、_progress揮発性にする必要がありますが、アクセスをロックする必要はありません。

于 2013-06-20T16:51:40.923 に答える
0

誰もオブジェクトの状態を変更しない場合、プロパティ/フィールドが読み取り専用であることは問題ではないと思います。

したがって、進行状況を設定する 1 つのスレッドとそれを読み取るスレッドしかない場合は、ロックは必要ありません。

その場合でも、Progress オブジェクトを不変にするのは良い設計です。なぜなら、設計で明示的に述べているからです。対象は変えられないからです。

また、後で変更/再設計 (progress オブジェクトの変更/ミューテーションを決定する) があった場合、誤ってスレッドのバグを導入することはできません。

volatile キーワードでさえ必要ないかもしれませんか? プログレス ティックが 1 つか 2 つ失われても気にしないからです。キーワードは、フィールドへの「アクセスのシリアル化」に関するものです。

于 2013-06-20T15:24:56.907 に答える