生产者消费者实战
本篇主要是通过一段JAVA代码来模拟生产者和消费者的工作流程,来介绍生产者消费者这一模式。
package com.pattern;
import java.util.ArrayList;
import java.util.List;
public class ProducerConsumerMain {
/**
* 缓冲区,生产者放入数据,消费者取出数据
*/
private static class Buffer {
/**
* 存取数据通过list来实现
*/
private List<Integer> data = new ArrayList<>();
/**
* 设置存放最大值,当data大小达到MAX时,不允许再放数据
*/
private static final int MAX = 2;
/**
* 设置取数的最小值,当data大小是MIN时,不允许再取数据
*/
private static final int MIN = 0;
public synchronized int get() {
while (MIN == data.size()) {
try {
// 相当于this.wait();当前方法处于等待状态,并释放this对象锁,释放this监视器
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
Integer i = data.remove(0);
// 释放this监视器,唤醒等待this监视器的线程,但该方法不会释放this对象锁
notifyAll();
return i;
}
public synchronized void put(int value) {
while (MAX == data.size()) {
try {
// 相当于this.wait();当前方法处于等待状态,并释放this对象锁,释放this监视器
wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
data.add(value);
// 释放this监视器,唤醒等待this监视器的线程,但该方法不会释放this对象锁
notifyAll();
}
}
private static class Consumer extends Thread {
private Buffer buffer;
private int number;
public Consumer(Buffer b, int number) {
buffer = b;
this.number = number;
}
@Override
public void run() {
int value;
for (int i = 0; i < 10; i++) {
// 从缓冲区中获取数据
value = buffer.get();
try {
// 模拟消费数据所用时间
sleep(1000);
} catch (InterruptedException e) {
}
System.out.println("消费者 #" + this.number + " got: " + value);
}
}
}
private static class Producer extends Thread {
private Buffer buffer;
private int number;
public Producer(Buffer b, int number) {
buffer = b;
this.number = number;
}
@Override
public void run() {
for (int i = 0; i < 10; i++) {
try {
// 模拟生产数据所用时间
sleep(500);
} catch (InterruptedException e) {
}
// 将数据放入缓冲区
buffer.put(i);
System.out.println("生产者 #" + this.number + " put: " + i);
}
}
}
/**
* 模拟生产者消费者行为
*
* @param args
*/
public static void main(String[] args) {
Buffer buffer = new Buffer();
Producer p1 = new Producer(buffer, 1);
Consumer c1 = new Consumer(buffer, 1);
p1.start();
c1.start();
}
}
浙公网安备 33010602011771号