利用阻塞队列可以轻松实现生产者和消费者,不过我们也可以通过wait和notify来手动实现PV。
利用List建立一个仓库,实现put(),和take()方法。其中生产者调用put,当仓库满后wait(),每次调用都执行notify唤醒消费者;消费者调用take,当仓库空后wait(),每次调用都执行notify唤醒生产者。
代码如下:
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
public class ProducerConsumerModel {
public static void main(String[] args) {
EventStorage eventStorage = new EventStorage();
Producer producer = new Producer(eventStorage);
Consumer consumer = new Consumer(eventStorage);
new Thread(producer).start();
new Thread(consumer).start();
}
}
class Producer implements Runnable{
private EventStorage storage;
public Producer(EventStorage storage) {
this.storage = storage;
}
@Override
public void run() {
for(int i=0;i<100;i++){
storage.put();
}
}
}
class Consumer implements Runnable{
private EventStorage storage;
public Consumer(EventStorage storage) {
this.storage = storage;
}
@Override
public void run() {
for(int i=0;i<100;i++){
storage.take();
}
}
}
class EventStorage{
private int maxSize;
private List<Date> storage;
public EventStorage(){
maxSize = 10;
storage = new ArrayList<>();
}
public synchronized void put(){
while(storage.size()==maxSize){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
storage.add(new Date());
System.out.println("仓库里有了"+storage.size()+"个产品");
notify();
}
public synchronized void take(){
while(storage.size()==0){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("拿到了"+storage.remove(0)+",现在仓库还剩下"+storage.size());
notify();
}