Java多線程併發之生產者和消費者模式使用wait()和notify()通信方法實現

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阻塞隊列實現生產者和消費者模式

9、遇到困難可以評論(有信必回)小軒微信17382121839。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章