[解決済み] 何がメソッドをスレッドセーフにするのか?そのルールは?
質問
あるメソッドをスレッドセーフにするための全体的なルールやガイドラインはありますか?一回限りの状況がたくさんあることは理解していますが、一般的にはどうなのでしょうか?こんなに単純なことなのでしょうか?
- メソッドがローカル変数にしかアクセスしない場合は、スレッドセーフです。
そうなんですか?静的メソッドにも適用されるのでしょうか?
ある答えは、@Cybisさんから提供されたものです。
各スレッドが独自のスタックを取得するため、ローカル変数をスレッド間で共有することはできません。
静的メソッドもそうなのでしょうか?
あるメソッドに参照オブジェクトが渡された場合、スレッドセーフは破られるのか?しかし、いくつかのルールを使って、メソッドがスレッドセーフであることを確認するためのガイドラインを定義できればと思いました。
スレッドセーフなメソッドを定義するルールの短いリストはありますか?もしそうなら、それは何ですか?
EDIT
ここでは、多くの良い点が指摘されています。この質問に対する本当の答えは、「スレッドの安全性を確保するための単純なルールは存在しない」だと思います。素晴らしい。しかし
一般に
受理された回答は、良い、短い要約を提供していると思います。例外は常にあります。それはそれとして。私はそれに耐えることができます。
解決方法は?
メソッド(インスタンスまたは静的)がそのメソッド内にスコープされた変数だけを参照する場合、各スレッドが独自のスタックを持つため、それはスレッドセーフです。
この例では、複数のスレッドが
ThreadSafeMethod
を同時に実行しても問題ありません。
public class Thing
{
public int ThreadSafeMethod(string parameter1)
{
int number; // each thread will have its own variable for number.
number = parameter1.Length;
return number;
}
}
これは、ローカルにスコープされた変数のみを参照する他のクラスのメソッドを呼び出す場合にも当てはまります。
public class Thing
{
public int ThreadSafeMethod(string parameter1)
{
int number;
number = this.GetLength(parameter1);
return number;
}
private int GetLength(string value)
{
int length = value.Length;
return length;
}
}
もしメソッドが(オブジェクトの状態の)プロパティやフィールド(インスタンスまたは静的)にアクセスする場合は、ロックを使って、値が別のスレッドによって変更されないようにする必要があります。
public class Thing
{
private string someValue; // all threads will read and write to this same field value
public int NonThreadSafeMethod(string parameter1)
{
this.someValue = parameter1;
int number;
// Since access to someValue is not synchronised by the class, a separate thread
// could have changed its value between this thread setting its value at the start
// of the method and this line reading its value.
number = this.someValue.Length;
return number;
}
}
メソッドに渡されるパラメータが構造体でも不変でもない場合、メソッドの範囲外の別のスレッドによって変異させられる可能性があることに注意する必要があります。
適切な並行性を確保するためには、ロックを使用する必要があります。
をご覧ください。 lockステートメント C#リファレンス と ReadWriterLockSlim .
ロック
は、主に1つずつ機能を提供するのに便利です。
ReadWriterLockSlim
は、複数のリーダと単一のライタが必要な場合に便利です。
関連
-
[解決済み] [Entity Framework 4.1でエンティティに関連オブジェクトを追加する際に、エンティティオブジェクトをIEntityChangeTracker.の複数のインスタンスから参照できない。
-
[解決済み】WPFでXamlファイルにコメントを追加する方法は?
-
[解決済み】Entity FrameworkからのSqlException - セッション内で他のスレッドが動作しているため、新しいトランザクションは許可されません。
-
[解決済み] 他のスレッドからGUIを更新するにはどうすればよいですか?
-
[解決済み] C#のStringとstringの違いは何ですか?
-
[解決済み] C#の正しいバージョン番号を教えてください。
-
[解決済み] C#のオートプロパティに初期値を与える最良の方法は何ですか?
-
[解決済み] C#の[Flags]Enum属性の意味とは?
-
[解決済み] なぜList<T>を継承しないのですか?
-
[解決済み] 非同期静的メソッドは、静的クラス変数を変更しないのであれば、スレッドセーフですか?
最新
-
nginxです。[emerg] 0.0.0.0:80 への bind() に失敗しました (98: アドレスは既に使用中です)
-
htmlページでギリシャ文字を使うには
-
ピュアhtml+cssでの要素読み込み効果
-
純粋なhtml + cssで五輪を実現するサンプルコード
-
ナビゲーションバー・ドロップダウンメニューのHTML+CSSサンプルコード
-
タイピング効果を実現するピュアhtml+css
-
htmlの選択ボックスのプレースホルダー作成に関する質問
-
html css3 伸縮しない 画像表示効果
-
トップナビゲーションバーメニュー作成用HTML+CSS
-
html+css 実装 サイバーパンク風ボタン
おすすめ
-
[解決済み】Ajax処理で「無効なJSONプリミティブ」と表示される件
-
[解決済み] メンバー '<メンバー名>' にインスタンス参照でアクセスできない
-
[解決済み】C#におけるtypedefの等価性
-
[解決済み】WebForms UnobtrusiveValidationModeは、jqueryのScriptResourceMappingを必要とする
-
[解決済み】Sequence contains no matching element(シーケンスにマッチする要素がない
-
[解決済み】値が期待した範囲に収まらない
-
[解決済み] EntityTypeにキーが定義されていないエラー
-
[解決済み】Unity 「関連するスクリプトを読み込むことができません」「Win32Exception: システムは指定されたファイルを見つけることができません"
-
[解決済み】C#のequal to演算子でtextとvarcharのデータ型は互換性がない
-
[解決済み】Microsoft.Extensions.LoggingからILoggerを解決することができない