如何手写一个生产者生产者消费者模型?(生产者消费者模型可以有多种实现,可以使用各种数据结构,现在记载的是最基础的生产者消费者单线程并且消息队列是由ArrayList来实现的,后续学会了再来更新嘻嘻)
整体模型的总结:
- 大体分为消费者模型、生产者模型、消息队列模型,其中消息队列模型是最复杂的。
- 生产者模型最基本的可以是使用for循环产生int类型的数字向消息队列中进行添加,即直接调用消息队列类中的add()方法即可。
- 同理,消费者模型就是在消息队列中取出相应的值即可,可以调用消息队列模型中的remove()方法。
ArrayList代码实现:
- 消息队列模型:创建ArrayList对象,该类的主体其实就是添加消息的方法和消费消息的方法;使用wait()方法和notifyAll()方法来实现阻塞队列的要求,当消息队列中消息达到最大值即当前线程进行等待,其中通过synchronized关键字实现每次生产消费都只有一个线程在操作。
- 生产者模型和消费者模型:没有什么花里胡哨的,最主要的就是调用消息队列模型的添加和删除的方法即可,为了更好的展示阻塞,使用sleep()方法使得生产者生产更快,消费更慢。
public class PublicQueue {
private int maxCount = 50;//缓冲区最大长度
private ArrayList arrayList = new ArrayList();
public synchronized void add(int msg){
if (arrayList.size() == maxCount){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
notifyAll();
}
arrayList.add(msg);
System.out.println("生产一个产品为" + msg + ",链表整体容量还有" + arrayList.size() + "个元素");
}
public synchronized void remove(){
if (arrayList.size() == 0){
try {
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}else {
notifyAll();
}
int msg = (int) arrayList.get(arrayList.size()-1);
arrayList.remove(arrayList.size()-1);
System.out.println("消费一个产品"+ msg + "剩余队列长度为" + arrayList.size());
}
}
public class ProducerThread extends Thread{
private PublicQueue publicQueue;
public ProducerThread(PublicQueue publicQueue){
this.publicQueue = publicQueue;
}
@Override
public void run() {
for (int i = 1; i <= 60; i++){
publicQueue.add(i);
try {
Thread.sleep(100);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
public class ConsumerThread extends Thread{
private PublicQueue publicQueue;
public ConsumerThread(PublicQueue publicQueue){
this.publicQueue = publicQueue;
}
@Override
public void run() {
for (;;){
publicQueue.remove();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
}
}
.......