解决方法1–管程法
生产者将生产好的数据放入缓冲区,消费者从缓冲区拿出数据
- 如果缓冲区满了,就让生产者进行等待区域,直到缓冲区不满为止。
- 如果缓冲区为0,就让消费者进入等待区域,直到缓冲区有产品。
- wait(),让当前进程进入等待,即让线程释放出共享对象的锁
- notify(),会让调用了wait()系列方法的一个线程释放锁,并通知其他正在等待的线程得到锁
- notifyAll(),会唤醒所有在共享变量上由于调用了wait系列方法而被挂起的线程。
package com.yf.communication;
//测试生产者消费者模型-->利用缓冲区解决:管程法
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
//生产者,消费者,产品,缓冲区
public class TestPC {
public static void main(String[] args) {
SynContainer container = new SynContainer();
Productor productor = new Productor(container);
Consumer consumer = new Consumer(container);
productor.start();
consumer.start();
}
}
class Productor extends Thread{
private SynContainer container;
public Productor(SynContainer container) {
this.container = container;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
container.push(new Chicken(i));
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("生产了第"+i+"只鸡");
}
}
}
class Consumer extends Thread{
private SynContainer container;
public Consumer(SynContainer container) {
this.container = container;
}
@Override
public void run() {
for (int i = 0; i < 100; i++) {
try {
container.get();
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("消费了第"+i+"只鸡");
}
}
}
class Chicken{
int id;//产品编号
public Chicken(int id) {
this.id = id;
}
}
class SynContainer{
List<Chicken> list = new ArrayList<>();
static final int MAXSIZE = 10;
//生产者放入产品
public synchronized void push(Chicken chicken) throws InterruptedException {
while(list.size() == MAXSIZE){//如果满了就让生产者线程一直循环等待。当消费者线程拿出了产品之后,再进行生产
this.wait();
}
if(list.size()<MAXSIZE){
//没有满就放入产品
list.add(chicken);
}
this.notifyAll();
}
//消费者消费产品
public synchronized Chicken get() throws InterruptedException {
while(list.size()==0){
this.wait();
}
if(list.size()>0){
Chicken chicken = list.remove(0);
this.notifyAll();
return chicken;
}
return null;
}
}