线程间进行通信时,生产者与消费者模式得到了很广泛的应用。下面是用java实现的一个例子。
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
public class Test2 {
public static void main(String[] args) {
Restaurant restaurant = new Restaurant();
Product product = new Product(restaurant);
Consumer consumer = new Consumer(restaurant);
int cpus = Runtime.getRuntime().availableProcessors();
ExecutorService service = new ThreadPoolExecutor(cpus, cpus * 2, 2, TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(16), new ThreadPoolExecutor.CallerRunsPolicy());
service.submit(product);
service.submit(consumer);
service.shutdown();
}
}
/**
* 生产者
*/
class Product extends Thread {
private Restaurant restaurant;
public Product(Restaurant restaurant) {
this.restaurant = restaurant;
}
@Override
public void run() {
while (!restaurant.isFlag()) {
restaurant.addNumbers();
restaurant.push(new Meal(restaurant.getNumbers()));
System.out.println("厨师正在制作第----" + restaurant.getNumbers() + "----份食物");
}
}
}
/**
* 消费者
*/
class Consumer extends Thread {
private Restaurant restaurant;
public Consumer(Restaurant restaurant) {
this.restaurant = restaurant;
}
@Override
public void run() {
while (!restaurant.isFlag()) {
Meal meal = restaurant.pop();
System.out.println("消费者站在消费第----" + meal.getId() + "----份食物");
}
}
}
class Meal {
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public Meal(int id) {
this.id = id;
}
}
class Restaurant {
/**
* 缓冲区大小
*/
private static final int BUFFER_SIZE = 20;
/**
* 缓冲区,存放食物的数组
*/
Meal[] meals = new Meal[BUFFER_SIZE];
/**
* 缓冲区下标
*/
private int count = 0;
/**
* 制作的总份数
*/
private int numbers = 0;
/**
* 餐厅休息标志
*/
private boolean flag = false;
/**
* 厨师一天制作最大数量
*/
private static final int MAX_COUNT = 10;
public int getNumbers() {
return numbers;
}
public void addNumbers() {
this.numbers++;
}
public boolean isFlag() {
return flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
/**
* 生产食物
*
* @param meal
*/
public synchronized void push(Meal meal) {
//大于缓冲区,等待,去消费食物
if (count == BUFFER_SIZE - 1) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//制作食物
count++;
meals[count] = meal;
//唤起所有等待的线程
this.notifyAll();
if (numbers == MAX_COUNT) {
setFlag(true);
}
}
/**
* 消费食物
*/
public synchronized Meal pop() {
//缓冲区没有食物,等待,去制作食物
if (count == 0) {
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
//消费食物
Meal meal = meals[count];
count--;
//唤起所有等待的线程
this.notifyAll();
return meal;
}
}