c# - Javaの同期されたキーワードのC#のバージョン?


C#は独自のバージョンのjava "synchronized"キーワードを持っていますか?

すなわち、Javaでは関数、オブジェクト、またはコードブロックのいずれかに指定することができます。

public synchronized void doImportantStuff() {
   // dangerous code goes here.
}

または

public void doImportantStuff() {
   // trivial stuff

   synchronized(someLock) {
      // dangerous code goes here.
   }
}


Answers


最初のクラスはスレッドセーフである必要はありません。 YAGNIを使用してください:あなたが実際にそれを使用しようとしていることを知っているときにスレッドセーフを適用するだけです(そしてテストしてください)。

メソッドレベルのものには、 [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

個人的には、これをロックthisMethodImpl typeof(Foo)ロックするので、 MethodImplの実装がMethodImplないのはベストプラクティスではありません。 推奨されるオプションは、独自のロックを使用することです。

private readonly object syncLock = new object();
public void SomeMethod() {
    lock(syncLock) { /* code */ }
}

フィールドのようなイベントの場合、ロックの実装はコンパイラによって異なります。 古いMicrosoftコンパイラではlock(this) / lock(Type)が、 最近のコンパイラではInterlocked更新が使用されています。

これにより、より詳細な使用が可能になり、 Monitor.Wait / Monitor.Pulseなどを使用してスレッド間で通信することができます。

関連するブログエントリ (後で再訪 )。




static object Lock = new object();

lock (Lock) 
{
// do stuff
}



C#は独自のバージョンのjava "synchronized"キーワードを持っていますか?

いいえ。C#では、非同期スレッド間で同期して作業するリソースを明示的にlockします。 lockはブロックを開きます。 メソッドレベルでは機能しません。

ただし、実行時にMonitor.Enter (およびその後Monitor.Exit )を呼び出すことによってlock機能するため、基本となるメカニズムは似ています。 Sunのマニュアルによれば、Javaも同じように動作します




代わりにlockステートメントを使用できます。 私はこれが第2版を置き換えることができると思う。 また、 synchronizedlock両方がオブジェクトに対して操作する必要があることに注意してください。




[MethodImpl(MethodImplOptions.Synchronized)]ように表示されます。

[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]