1 、バックグラウンドの例
プリンタは、二つのことを実行します。
最初のイベントは、それらをキュープリントに印刷ジョブを追加し、他のコンピュータを含む印刷外の要求を、受け入れる責任です。
もう一つは、印刷キューから印刷ジョブをプリントアウトされ、印刷ジョブが完了すると、印刷ジョブが削除されます。
確かに、これら二つのことを同時にしている、それは新しい印刷ジョブを受け入れるために、印刷されないようにプリンタを持っていることは不可能である、インクがその紙の腐敗ので、乾くまで待って、要求を受け入れるようにし、印刷していないことは不可能でしたインクルード
我々は、プリンタが、その後明らかに、私たちはもちろん、同時に2つのことを行うために、2つのスレッドを使用するだけでなく、他のことを考えることができ、プログラムで作業できるようにする場合は、リソースの競合によってが複雑になるので、それは、並行性の問題以前に言われている - プリンタキュー。
理想的には、印刷要求操作を受け付ける二つのスレッドを実行することができる最高の選択肢は、その後、むしろ要求を受け入れるよりも、印刷動作を行うようにしたい N 時間後に印刷ジョブを実行するために、私たちはまた、スレッドに対処する必要がありますスレッドの協力の問題であるとの連携を、作業。
コラボレーションのスレッドは、我々は3つの質問を考慮してください。
(1)現在のスレッドの他のスレッドの実行を通知する方法
(2)現在のスレッドの実行を防ぐ方法
他のスレッドが現在のスレッドの実行を継続するために終了する方法(3)
答:( 1 ) Monitor.Pulse()
(2)Monitor.Wait()
(3)Monitor.Wait()
2 、無プリンタワーカーコラボレーション
クラスMonitorTest { INT MAX = 10 ; // 最大印刷ジョブ10 キュー < INT >キュー; //はFIFOのオブジェクトセットを表す パブリックMonitorTestを() { キュー = 新しい新しいキュー< 整数 > (); } // メソッドプロデューサスレッドは、呼び出し:印刷ジョブは、アナログ加算される パブリック ボイドProducerThread() { ランダムR&LT = 新しい新しいランダム(); ロック(キュー) { ため(INT=カウンタ0 ;カウンタ<MAX、カウンタ++ ) { int型値= r.Next(100 ); queue.Enqueue(値); // キューに乱数 Console.WriteLineを(" 製造:" + 値); } } } / / コンシューマスレッド 公共 ボイドConsumerThread() { ロック(キュー) { ための(int型のカウンタ= 0 ;カウンタ<MAX、カウンタ++ ) { int型値=(INT)queue.Dequeue(); // 第一个元素出队列 Console.WriteLineを(" 消费:" +の値)。 } } } 静的 ボイドメイン(文字列[]引数) { MonitorTestモニター = 新しいMonitorTest()。 スレッドプロデューサー = 新しいスレッド(新しいThreadStart(monitor.ProducerThread)); スレッドの消費者 = 新しいスレッド(新しいですThreadStart(monitor.ConsumerThread)); producer.Start(); consumer.Start(); Console.WriteLineを(" 仕事の後にプリンタ" ); Console.ReadLine(); } }
結果:最初にすべての生産タスクが入ってくる追加し、ジョブの消費を行います。これが我々の要求に沿ったものではありません。私たちは、印刷ジョブを追加している消費者ジョブの実装を必要と
3 、プリンタワーカーコラボレーション
クラスMonitorTest { INT MAX = 10 ; // 最大印刷ジョブ10 キュー < INT >キュー; //はFIFOのオブジェクトセットを表す パブリックMonitorTestを() { キュー = 新しい新しいキュー< 整数 > (); } // メソッドプロデューサスレッドは、呼び出し:印刷ジョブは、アナログ加算される パブリック ボイドProducerThread() { ランダムR&LT = 新しい新しいランダム(); ロック(キュー) { ため(INT=カウンタ0 ;カウンタ<MAX、カウンタ++ ) { int型値= r.Next(100 ); queue.Enqueue(値); // キューに乱数 Console.WriteLineを(" 製造:" + 値); // プロデューサスレッドレディキュー入力するキューのブロッキングから消費者のスレッドに通知 Monitor.Pulse(キュー); // 待機中のスレッドリリース // ブロックされたキューにプロデューサーのスレッドを、ロックをあきらめ、実行される消費者のスレッド Monitor.Wait(キュー); // CosumerThreadを待ちます()完了します } } } // 消費者のスレッドを 公共 のボイドConsumerThread() { ロック(キュー) { 行う { IF(queue.Count> 0 ) { int型の値が=(int型)queue.Dequeue(); // キューの最初の要素 Console.WriteLineを(" 消費者:" + 値); Monitor.Pulse(キュー); // 解放 } } ながら(Monitor.Wait(キュー)); // データにProducerThread()を待ちます } } 静的 ボイドメイン(文字列[]引数) { MonitorTestモニター = 新しいMonitorTest()。 スレッドプロデューサー = 新しいスレッド(新しいThreadStart(monitor.ProducerThread)); スレッドの消費者 = 新しいスレッド(新しいThreadStart(monitor.ConsumerThread)); producer.Start(); consumer.Start(); Console.WriteLineを(" 打印机工作完毕" ); Console.ReadLine(); } }
説明:
場合プロデューサスレッドが起動し、動作状態に入った後、開始後、乱数を生成し、およびに追加されたキューのキュー・コンテナ、その後コードを横切る Monitor.Pulse(キュー); 次いで、プロデューサスレッド通知スレッドのコンシューマレディキューにキューをブロックから。そして、プロデューサーのスレッドはに走ったMonitor.Wait(キュー); 生産待ち状態にスレッド(すなわち、彼を阻止する)、彼はあきらめたキューロックされ、そのスレッドの消費者は、実行されます。
そして、スレッド消費者の実行時に実行しながら、**行うに起因する最初のパフォーマンスにでサイクリング、そう直接から、条件を判断していないキューキュー「コールアウト」の最初の要素、そして彼は、コード会った(Monitor.Pulseをキュー)、その後、スレッド消費者に通知するためにプロデューサレディキューを入力するようにキューをブロックからのスレッドを、彼は判断しばらく(Monitor.Wait(キュー) )、これは最初の性能であるため、それほど
结果显示是 生产者生产一个,消费者接着就消费一个。如此循环中。。。