多线程通过管程法实现生产消费者模式需要借助中间容器作为换从区,还包括生产者、消费者。下面以蒸馒头为列,写一个demo。
中间容器:
为了防止数据错乱,还需要给生产和消费方法加锁
并且生产者在容器写满的情况下需要等待消费者消费,
同理消费者在容器为空的情况下需要等待生产者生产
//缓冲区
class SynContainer{
Steamebun[] buns = new Steamebun[10];// 缓冲容器
int count = 0; // 计数器
// 生产 存储
public synchronized void push(Steamebun bun) {
// 容器没有空间不能生产
if(count == buns.length) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 容器有空间可以生产
buns[count++] = bun;
// 存在数据了,通知对方消费
this.notifyAll();
}
// 消费 获取
public synchronized Steamebun pop(){
// 没有数据了,只能等待
if(count == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
// 存在数据了可以消费
Steamebun bun = buns[--count];
// 容器存在空间了,通知对方生产
this.notifyAll();
return bun;
}
}
生产者:
生产者和消费者共享容器资源
//生产者
class Productor extends Thread{
SynContainer container;
public Productor(SynContainer container) {
this.container = container;
}
@Override
public void run() {
// 生产
for (int i = 0; i < 100; i++) {
System.out.println("生产-->" + i + "馒头");
container.push(new Steamebun(i));
}
}
}
消费者:
//消费者
class Consumer extends Thread{
SynContainer container;
public Consumer(SynContainer container) {
this.container = container;
}
@Override
public void run() {
// 消费
for (int i = 0; i < 100; i++) {
System.out.println("消费-->" + container.pop().id + "馒头");
}
}
}
测试代码:
public class Cotest01 {
public static void main(String[] args) {
SynContainer container = new SynContainer();
new Productor(container).start();
new Consumer(container).start();
}
}
运行:
可以看到生产多少生产多少。