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();
}
}