Java知識點——線程通信(線程之間的聯繫)

1. 生活化例子

預約 --> 搶購
消費者 <–> 商品 <–> 生產者

消費者
1. 購買商品
2. 等待,不過在等待之前,需要告知生產者快點生產

生產者:
1. 生產商品
2. 休息,在休息之前,要告知消費者你快來買啊

商品:
就是兩個獨立線程之間的共享資源。

2. 共享資源處理問題

現在存在兩個完全無關的線程:生產者和消費者,但是商品會作爲他們兩者之間的共享資源。
生產者和消費者中都有一個成員變量 商品類型

【解決方案】
創建生產者或者消費者線程對象時,使用同一個商品類對象,作爲構造方法參數進行初始化操作

3. 設計程序

在這裏插入圖片描述

代碼如下:
消費者

package thread;


public class Customor implements Runnable{
	private Goods goods = null;
	
	public Customor() {
		super();
	}
	public Customor(Goods goods) {
		super();
		this.goods = goods;
	}
	
	@Override
	public void run() {
		while (true) {
			synchronized (goods) {
				try {
					Thread.sleep(100);
				} catch (InterruptedException e1) {
					// TODO Auto-generated catch block
					e1.printStackTrace();
				}
				if (!goods.isProduct()) {
					System.out.println("消費者購買" + goods.getName() + ":" + goods.getPrice());

					goods.setProduct(true);
					// 沒貨了
					System.out.println("喚醒生產者");
					// 喚醒生產者Producer線程
					goods.notify();
				} else {
					// 此時商品狀態爲true,也就是說,沒商品,需要生產
					System.out.println("消費者進入無線等待狀態");
					try {
						goods.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
}

生產者:

package thread;

public class Producer implements Runnable{
	
	private Goods goods = new Goods();
	
	public Producer() {
		super();
	}

	public Producer(Goods goods) {
		super();
		this.goods = goods;
	}

	@Override
	public void run() {
		while (true) {
			synchronized (goods) {

				try {
					Thread.sleep(100);
				} catch (InterruptedException e) {
					// TODO Auto-generated catch block
					e.printStackTrace();
				}

				if (goods.isProduct()) {
					// 這裏是一個數學方法,概率設定
					if (Math.random() > 0.5) {
						goods.setName("紅燒茄子");
						goods.setPrice(25);
					} else {
						goods.setName("蛋炒飯");
						goods.setPrice(15);
					}

					// 修改標記
					goods.setProduct(false);
					System.out.println("生產了" + goods.getName() + "價格:" + goods.getPrice());

					// 喚醒消費者
					System.out.println("喚醒消費者");
					goods.notify();

				} else {
					System.out.println("生產者進入無限等待");
					try {
						goods.wait();
					} catch (InterruptedException e) {
						// TODO Auto-generated catch block
						e.printStackTrace();
					}
				}
			}
		}
	}
}

商品:

package thread;

public class Goods {	
	private String name;
	private float price;
	private boolean product;
	
	public Goods(){}

	public Goods(String name, float price, boolean product) {
		super();
		this.name = name;
		this.price = price;
		this.product = product;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public float getPrice() {
		return price;
	}

	public void setPrice(float price) {
		this.price = price;
	}

	public boolean isProduct() {
		return product;
	}

	public void setProduct(boolean product) {
		this.product = product;
	}
}

主函數:

package thread;

public class Demo1 {
	public static void main(String[] args) {
		Goods goods = new Goods("鍋巴肉片",35,true);
		
		
		//這是按部就班  還可以使用匿名對象來調用start方法
		//day22SL  可見
		Producer producer = new Producer(goods);
		Customor customor = new Customor(goods);
		
		Thread thread1 = new Thread(producer);
		Thread thread2 = new Thread(customor);
		
		thread1.start();
		thread2.start();
	}
}

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