管程法
并发协作模型"生产者/消费者模式" ===> 管程法
生产者:负责生产数据的模块(可能是方法、对象、线程、进程)
消费者:负责处理数据的模块(可能是方法、对象、线程、进程)
缓冲区:消费者不能直接使用生产者的数据,他们之间有个缓冲区
生产者将生产好的数据放入缓冲区,消费者从缓冲区拿出数据
代码
package testthread.gaoji;
/**
* 测试生产者消费者模型:并发协作模型"生产者/消费者模式" ===> 管程法
* 生产者将生产好的数据放入缓冲区,消费者从缓冲区拿出数据
* 有4个要素
* 1.生产者
* 2.消费者
* 3.产品
* 4.缓冲区
*/
public class TestPC {
public static void main(String[] args) {
SyncContainer container = new SyncContainer();
new Producer(container).start();
new Consumer(container).start();
}
}
//生产者
class Producer extends Thread {
SyncContainer container;
public Producer(SyncContainer container) {
this.container = container;
}
//生产
@Override
public void run() {
for (int i = 0; i < 100; i++) {
container.push(new Product(i));
System.out.println("将产品放入缓冲区:" + i);
}
}
}
//消费者
class Consumer extends Thread {
SyncContainer container;
public Consumer(SyncContainer container) {
this.container = container;
}
//消费
@Override
public void run() {
for (int i = 0; i < 100; i++) {
System.out.println("消费产品" + container.pop().getPid());
}
}
}
//产品
class Product {
private int pid;//产品编号
public int getPid() {
return pid;
}
public void setPid(int pid) {
this.pid = pid;
}
public Product(int pid) {
this.pid = pid;
}
}
//缓冲区
class SyncContainer {
//容器大小,默认容量指定10
private static final int DEFAULT_CAPACITY = 10;
Product[] products = new Product[DEFAULT_CAPACITY];
//容器计数器
int count = 0;
//生产者放产品
public synchronized void push(Product product) {
if (count == products.length) {
//容器已满,需要等待消费
//通知消费者消费,生产者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//容器不满,可以放产品
products[count] = product;
count++;
//通知消费者消费,这里用notifyAll和notify结果都是一样的,因为不会同时阻塞
this.notifyAll();
}
//消费者消费产品
public synchronized Product pop() {
//判断容器有无产品,无则阻塞
if (count == 0) {
//等待生产者生产,消费者等待
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//可以消费,这里主要:count--必须在前,因为生产者生产之后count++会+1
count--;
Product product = products[count];
//通知生产者生产,这里用notifyAll和notify结果都是一样的,因为不会同时阻塞
this.notify();
return product;
}
}