web-dev-qa-db-ja.com

JavaのsynchronizedキーワードのC#バージョン?

C#にはJava "synchronized"キーワードの独自のバージョンがありますか?

つまりJavaでは、次のように関数、オブジェクト、またはコードブロックのいずれかに指定できます。

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

または

public void doImportantStuff() {
   // trivial stuff

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

最初に-ほとんどのクラスはスレッドセーフである必要はありません。 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; }
}

フィールドに似たイベントareはデフォルトで同期されますが、自動実装プロパティare notに注意してください。

public int SomeProperty {get;set;} // not synchronized
public event EventHandler SomeEvent; // synchronized

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

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

フィールドのようなイベントの場合、ロックの実装はコンパイラに依存することに注意してください。古いMicrosoftコンパイラーではlock(this)/lock(Type)ですが、- 最近のコンパイラーではInterlockedを使用しています アップデート-厄介な部分のないスレッドセーフです。

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

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

437
Marc Gravell
static object Lock = new object();

lock (Lock) 
{
// do stuff
}
54
Jan Gressmann

C#にはJava "synchronized"キーワードの独自のバージョンがありますか?

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

ただし、lockはランタイムで Monitor.Enter (およびその後Monitor.Exit)を呼び出すことで機能するため、基本的なメカニズムは似ています。 Javaは、 Sunのドキュメント に従って、同じように機能します。

38
Konrad Rudolph

注意してください、フルパスで行:[MethodImpl(MethodImplOptions.Synchronized)]は次のようになります

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

7
Traubenfuchs

代わりにlockステートメントを使用できます。これは2番目のバージョンのみを置き換えることができると思います。また、synchronizedlockの両方がオブジェクトを操作する必要があることを忘れないでください。

5
James