當多個線程通過get/set-functions訪問屬性/字段時,是否有必要鎖定getter和setter?C#是否在必要的getter和setter中鎖定?
例如:
你有一個計時器,定期獲取對象的值。定期更新此值的過程。
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功能。
- 如果是,爲什麼?
- 是揮發性的必要在這種情況下(假設一個或多個處理器核)
- 爲了保持它的「簡單」讓我們假設屬性/從進展字段是隻讀的。 編輯:我知道+ =等等都沒有原子操作的,需要妥善處理指標(如鎖定)
我認爲設置和變量_progress閱讀是一個原子操作。 GetProgress將獲得非常當前的值並不重要。如果不是這次,它會在GetProgress的下一個調用中得到它。
如果'_progress'是引用類型,然後讀取和寫入它的值(即改變基準)確實是一個原子操作,這樣你就不會需要鎖定在你的榜樣的特定代碼。但是如果你在setter或getter中改變了多個字段,或者這個字段不是一個帶有原子讀/寫的類型(例如'double'),那麼你需要鎖定。 –
@MthetheWWatson:原子只是方程的一部分。如果您希望所有線程都讀取最近寫入的值,則可能需要鎖定。 (或顯式內存屏障。) –
與http://blogs.msdn.com/b/ericlippert/archive/2011/05/26/atomicity-volatility-and-immutability-are-different-part-one.aspx啓動 –