C#にはJava "synchronized"キーワードの独自のバージョンがありますか?
つまりJavaでは、次のように関数、オブジェクト、またはコードブロックのいずれかに指定できます。
public synchronized void doImportantStuff() {
// dangerous code goes here.
}
または
public void doImportantStuff() {
// trivial stuff
synchronized(someLock) {
// dangerous code goes here.
}
}
最初に-ほとんどのクラスはスレッドセーフである必要はありません。 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
などを使用できます。
static object Lock = new object();
lock (Lock)
{
// do stuff
}
C#にはJava "synchronized"キーワードの独自のバージョンがありますか?
いいえ。C#では、非同期スレッド間で同期的に作業するリソースを明示的にlock
します。 lock
はブロックを開きます。メソッドレベルでは機能しません。
ただし、lock
はランタイムで Monitor.Enter
(およびその後Monitor.Exit
)を呼び出すことで機能するため、基本的なメカニズムは似ています。 Javaは、 Sunのドキュメント に従って、同じように機能します。
注意してください、フルパスで行:[MethodImpl(MethodImplOptions.Synchronized)]
は次のようになります
[System.Runtime.CompilerServices.MethodImpl(System.Runtime.CompilerServices.MethodImplOptions.Synchronized)]
代わりにlock
ステートメントを使用できます。これは2番目のバージョンのみを置き換えることができると思います。また、synchronized
とlock
の両方がオブジェクトを操作する必要があることを忘れないでください。