C# には Java の「synchronized」キーワードの独自バージョンがありますか?
つまり、Java では、次のように関数、オブジェクト、またはコード ブロックのいずれかに指定できます。
public synchronized void doImportantStuff() {
// dangerous code goes here.
}
または
public void doImportantStuff() {
// trivial stuff
synchronized(someLock) {
// dangerous code goes here.
}
}
ベストアンサー1
まず、ほとんどのクラスはスレッドセーフである必要はありません。ヤグニ: 実際に使用(およびテスト)する予定であることがわかっている場合にのみ、スレッドセーフを適用します。
メソッドレベルのものについては、次のものがあります[MethodImpl]
:
[MethodImpl(MethodImplOptions.Synchronized)]
public void SomeMethod() {/* code */}
これはアクセサー (プロパティとイベント) でも使用できます。
private int i;
public int SomeProperty
{
[MethodImpl(MethodImplOptions.Synchronized)]
get { return i; }
[MethodImpl(MethodImplOptions.Synchronized)]
set { i = value; }
}
フィールドのようなイベントはデフォルトで同期されますが、自動実装されたプロパティは同期されないことに注意してください。
public int SomeProperty {get;set;} // not synchronized
public event EventHandler SomeEvent; // synchronized
個人的には、またはの実装はMethodImpl
ロックされるため好きではありません。これはベストプラクティスに反します。推奨されるオプションは、独自のロックを使用することです。this
typeof(Foo)
private readonly object syncLock = new object();
public void SomeMethod() {
lock(syncLock) { /* code */ }
}
フィールドのようなイベントの場合、ロックの実装はコンパイラに依存します。古いMicrosoftコンパイラでは、lock(this)
/ lock(Type)
- ですが、最近のコンパイラではInterlocked
更新 - 厄介な部分がないのでスレッドセーフです。
これにより、よりきめ細かい使用が可能になり、スレッド間の通信にMonitor.Wait
/ etc を使用できるようになります。Monitor.Pulse