1、簡介:
生產者和消費者模式生活當中隨處可見,它描述的是協調與協作的關係。比如餐廳廚師在準備食物,那麼廚師就是生產者,而來店裏喫飯的客戶則是消費者,消費者需要座子和椅子這就是公共的一個空間,在代碼裏座子和椅子則就是一個共享的對象。
2、需求
生產者:指的是生產好某樣東西放在一個公共的空間裏,這裏指的是放到餐盒裏
消費者:指的是從公共的空間裏取出生產好的東西,這裏指的是從餐盒裏取餐
餐盒:這裏我對餐盒的容量的定義是不能超過五個
3、餐盒代碼類
/**
* 存放餐的盒子 盒子這裏固定大小爲五個
* @author 小軒
*
*/
public class Box {
//餐的數量初始化爲0
private int meal = 0;
//廚師製作一份餐
public synchronized void create(){
//如果餐等於5即可等待消費少於5份的再生產
while (meal==5) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
meal++;
System.out.println("製作一份餐成功");
//喚醒等待的線程
notify();
}
//消費者購買一份餐
public synchronized void buy(){
//如果餐等於0份的時候 即代表等待生產線程去生產
while (meal==0) {
try {
wait();
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
meal--;
System.out.println("消費一份餐成功");
//喚醒等待的線程
notify();
}
}
4、生產者代碼類 (這裏定義生產10次)
/**
* 生產者
* @author 小軒
*
*/
public class Producter implements Runnable {
private Box box;
public Producter(Box box) {
// TODO Auto-generated constructor stub
this.box = box;
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 10; i++) {
System.out.println("生產者 i:"+(i+1));
try {
Thread.sleep(30);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
box.create();
}
}
}
5、消費者代碼類 (這裏定義消費10次)
/**
* 消費者
* @author 小軒
*
*/
public class Consumer implements Runnable{
private Box box;
public Consumer(Box box) {
// TODO Auto-generated constructor stub
this.box = box;
}
@Override
public void run() {
// TODO Auto-generated method stub
for (int i = 0; i < 10; i++) {
System.out.println("消費者 i:"+(i+1));
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
box.buy();
}
}
}
6、主程序類
public class Test {
/**
* 主程序入口
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
//實例化盒子
Box box = new Box();
//實例化生產者並且把盒子傳遞過去 用的是同一個盒子
Producter pro = new Producter(box);
//實例化消費者並且把盒子傳遞過去 用的也是同一個盒子
Consumer con = new Consumer(box);
//實例化兩個線程
Thread t1 = new Thread(pro);
Thread t2 = new Thread(con);
//啓動兩個線程
t1.start();
t2.start();
}
}
7、運行主程序類效果
8、這裏推薦使用阻塞隊列實現生產者和消費者模式
阻塞隊列實現生產者消費者模式超級簡單,它提供開箱即用支持阻塞的方法put()和take(),開發者不需要寫困惑的wait-nofity代碼去實現通信。BlockingQueue 一個接口,Java5提供了不同的現實,如ArrayBlockingQueue和LinkedBlockingQueue,兩者都是先進先出(FIFO)順序。而ArrayLinkedQueue是自然有界的,LinkedBlockingQueue可選的邊界。
點擊跳轉----》 Java多線程併發採用BlockingQueue阻塞隊列實現生產者和消費者模式