C#が、ロックモニタを使用して複数のスレッドにリソースの使用を制御する、最も一般的な問題は、生産者と消費者は、同期と通信の古典的な例をマルチスレッドということです。C#のマルチスレッドの同期と通信をご覧ください。
ロックとモニター上のI、
ロック時間内に排他的に他のスレッドが待機しなければならないしながら、唯一のスレッドが、実行に入ることができ、セグメントは相互に排他的な(クリティカルセクション)であると定義されるコードであることができます。次のように書式が定義されています。
ロック(表現)statement_block
追跡すべき対象物を表す式は、しばしば引用されます。一般的に、あなたはクラスのインスタンス、これの使用を保護したい場合は、その上に、クラス名を使用して、静的変数(静的メソッド内で、例えば、相互に排他的なコードセグメント)場合に保護。statement_blockは、相互に排他的なコードセグメントです。
公衆を対象に、マルチスレッドプログラムで使用された場合、スレッドの共有リソースを監視します。モニタは、特定のオブジェクトに関連付けられている必要があります。
第二に、生産者と消費者問題
スレッドはキューの要素を更新し、別のスレッドがキューから要素を取得する場合は、キューを維持し、同時に2つのスレッドが、その後、私たちは生産者のための要素の更新スレッドを呼び出すと仮定し、消費者のための糸要素の取得は語りました。
図1に示すように、操作対象
/// <要約>; ///操作対象 /// </要約>; パブリッククラスカウンタ { //更新及びデジタル読み取り 専用のint numberOfCounterを; //実行可能フラグを読み取り、デッドロックを防止することができます発生した プライベート= BOOL readFlagはfalseに、 公共のボイドの読み取り() { //ロックした後、これを読むための他の操作が完了した読み のロック(この) { //最初の待機に入り、flase行動を追った のIF(readFlag!) { 試み { //他のスレッドの読み取り、書き込みに入るのを待つ Monitor.Wait(この); } キャッチ(例外EX) { Console.WriteLineを(EX); } } Console.WriteLineを( "消費(取得):{0}"、numberOfCounter); //完全な消費リセット falseに= readFlagと、 Monitor.Pulse(この); } } 公共書き込みボイド(int型の数値) { //一度ロックされ、他の書き込みは、この時間の書き込み操作が完了するまで待機します ロック(この) { flaseとして//最初readFlag、次のように実行するために書かれたスキップ 現在読まれるのを待って、読んでいる場合を//動作実行Monitor.Pulse IF(readFlag) { { してみてください Monitor.Wait(この); } キャッチ(例外EX) { Console.WriteLineを(EX); } } numberOfCounter =数; Console.WriteLineを( "生産(アップデート):{0}"、numberOfCounter); リセット//生産終了している readFlagを= trueに; //同期を待つは、パルスによって達成される Monitor.Pulse(この); } } }
2、生産者と消費者
/// <まとめ>; ///プロデューサー /// </要約> パブリッククラスCounterWrite { カウンタカウンタ; //製造プロデューサの数 INTを1つの数量=; 公共CounterWrite(カウンタボックス、INT要求) { //構造機能 カウンタ=ボックス、 数量=要求は; } 操作対象に対する情報生成更新// )公共ボイド書き込み( { ため(intはI = 1; I&LTは、数量=; I ++の) counter.Write(I); } } / // <まとめ> ///消費者 /// </要約> パブリッククラスCounterRead { カウンタカウンタ; //製造プロデューサの数 INTを1つの数量=; 公共CounterRead(カウンタボックス、INT要求) { //コンストラクタ カウンタ=ボックス、 数量=リクエスト; } //操作対象から情報を取得するために、消費者 公共ボイド読みます() { ため(INT I = 1; I&LTは、数量=; I ++)は counter.Read(); } }
3、スレッド操作
カウンタカウンタ=新しいカウンタ(); =新しいCounterRead(カウンタ10)を読み取るCounterRead。 CounterWrite書き込み=新しいCounterWrite(カウンタ、10)。 スレッドTH1 =新しいスレッド(新しいThreadStart(read.Read)); スレッドTH2 =新しいスレッド(新しいThreadStart(write.Write)); th1.Start(); th2.Start(); th1.Join(); th2.Join(); Console.ReadLine();
ロックオブジェクト参照、初期readFlag制御スレッドにより、カウンタ・ロックが偽読み取りを待つ:Monitor.Wait(本)、
スレッド2が書き込まれ、その後実行し、readFlagを変更:Monitor.Pulseを(本)、通知キューにオブジェクトの状態が変更された要求スレッド、
スレッド1ロックこれは、読み出し動作を実行し、readFlagを変更し、スレッド1とスレッド2インタラクティブ書き込み操作が読み取ることができます。
同時に、そこに交互に更新されており、readFlagは、デッドロック状態を避けるため。