生産者の消費問題
アプリケーションシナリオ:プロデューサーとコンシューマーの問題
-
倉庫に保管できる商品は1つだけだとすると、生産者は生産した商品を倉庫に入れ、消費者は倉庫から商品を取り出して消費します。
-
倉庫に製品がない場合、生産者は製品を倉庫に入れます。そうでない場合は、生産を停止し、倉庫内の製品が消費者に持ち去られるまで待ちます。
-
倉庫に製品がある場合、消費者は消費のために製品を持ち去ることができます。そうでない場合は、消費を停止し、製品が再び倉庫に入れられるまで待ちます。
スレッド通信-分析
これはスレッド同期の問題です。プロデューサーとコンシューマーは同じリソースを共有し、プロデューサーとコンシューマーは条件として相互に依存します。
-
生産者の場合、消費者は製品を生産する前に待つように通知されるべきです。製品の製造後、消費者に直ちに消費を通知する必要があります。
-
消費者の場合、消費後、消費が終了し、消費のために新製品を生産する必要があることを生産者に通知する必要があります。
-
生産者/消費者問題では、同期だけでは不十分です
-
同期により、同じ共有リソースの同時更新を防ぎ、同期を実現できます
-
同期を使用して、異なるスレッド間でメッセージパッシング(通信)を実現することはできません
Javaは、スレッド間の通信の問題を解決するためのいくつかの方法を提供します
メソッド名 | 効果 |
---|---|
待つ() | スレッドが他のスレッドから通知されるまで待機していることを示します。スリープとは異なり、ロックは解放されます。 |
待機(長いタイムアウト) | 待機するミリ秒数を指定します |
notify() | 待機状態でスレッドをウェイクアップします |
notifyAll() | 同じオブジェクトでwait()メソッドを呼び出すすべてのスレッドをウェイクアップし、優先度の高いスレッドが最初にスケジュールされます |
注:Objectクラスのすべてのメソッドは、同期メソッドまたは同期コードにのみ含めることができます
解決策1
並行コラボレーションモデル「生産者/消費者モデル」—>管理方法
-
プロデューサー:データの生成を担当するモジュール(メソッド、オブジェクト、スレッド、プロセスなど)。
-
コンシューマー:データの処理を担当するモジュール(メソッド、オブジェクト、スレッド、プロセスなど)。
-
バッファー:コンシューマーはプロデューサーのデータを直接使用できません。それらの間に「バッファー」があります。
-
プロデューサーは生成されたデータをバッファーに入れ、コンシューマーはバッファーからデータを取り出します
解決策2
並行コラボレーションモデル「生産者/消費者モデル」—>セマフォ方式