プロデューサー、コンシューマーモデルメンバー
プロデューサー:製品を生産してキューに入れます。
コンシューマー:コンシューマー製品。
キュー:データバッファー領域。
利点
1.レンコンのロックを解除します
生産者は生産にのみ注意を払い、消費者は消費にのみ注意を払います
2.非同期
同期:aはbを呼び出し、aはbと通信
する前にbが接続されるのを待つ必要があります非同期:aはWeChatをbに送信し、aは応答を待つ必要はなく、bは応答する必要はなく、bは待つことができます自由に返信
3.バランス速度差
プロデューサーの生産速度はコンシューマーの消費速度と等しくなければなりません。
そうでない場合、
生産>消費によりキューがオーバーフローし、
生産<消費によりキューが空になります。
通知メカニズム
wait():現在のスレッドを
notify()を待機させます:スレッドをウェイクアップします
notifyAll():すべてのスレッドをウェイクアップします
ロジック:Q3のスレッドが起動され、Q1に入り、ロックを取得すると、ロックを取得したスレッドがQ2の操作を実行します。操作を実行する前に、キューがいっぱいか、いっぱいか、待機して、操作を実行します。満杯になっていない場合は、ロックを解除してください。
Q2はスレッドを1つしか持てないため、Q1ではオブジェクトモニターロックメカニズムが使用されます。
コード:
public class Producer implements Runnable{
private Queue<Product> queue;
private int maxCapacity;
public Producer(Queue queue, int maxCapacity) {
this.queue = queue;
this.maxCapacity = maxCapacity;
}
@Override
public void run() {
synchronized (queue) {
while (queue.size() == maxCapacity) {
//一定要用 while,而不是 if,下文解释
try {
System.out.println("生产者" + Thread.currentThread().getName() + "等待中... Queue 已达到最大容量,无法生产");
wait();
System.out.println("生产者" + Thread.currentThread().getName() + "退出等待");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (queue.size() == 0) {
//队列里的产品从无到有,需要通知在等待的消费者
queue.notifyAll();
}
Random random = new Random();
Integer i = random.nextInt();
queue.offer(new Product("产品" + i.toString()));
System.out.println("生产者" + Thread.currentThread().getName() + "生产了产品:" + i.toString());
}
}
}
論理:
1.プロデューサーはロックを取得し、作業を開始し、プロダクションボックスがいっぱいか、いっぱいかを確認し、待機します
2.生産者はロックを取得し、作業を開始し、生産ボックスがいっぱいかどうかを確認し、生産ボックスに製品があるかどうかを確認します。ない場合は、消費者に通知します。
生産開始
public class Consumer implements Runnable{
private Queue<Product> queue;
private int maxCapacity;
public Consumer(Queue queue, int maxCapacity) {
this.queue = queue;
this.maxCapacity = maxCapacity;
}
@Override
public void run() {
synchronized (queue) {
while (queue.isEmpty()) {
try {
System.out.println("消费者" + Thread.currentThread().getName() + "等待中... Queue 已缺货,无法消费");
wait();
System.out.println("消费者" + Thread.currentThread().getName() + "退出等待");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
if (queue.size() == maxCapacity) {
queue.notifyAll();
}
Product product = queue.poll();
System.out.println("消费者" + Thread.currentThread().getName() + "消费了:" + product.getName());
}
}
}
論理:
1.消費者はロックを取得し、製品の消費を開始し、生産ボックスが空であるかどうかを確認し、空であるかどうかを確認します。
2.消費者はロックを取得して製品の消費を開始し、生産ボックスが空であるか空ではないか、および生産ボックスが製品でいっぱいであるかどうかを確認します。
生産者が製品を生産し、製品を消費し始めることを知ってください