多線程的開發中有一個最經典的操作案例,就是生產者-消費者,生產者不斷生產產品,消費者不斷取走產品。
sleep與wait區別:
sleep: 讓線程進行進入休眠狀態,讓出cpu的時間片,不釋放監視器所有權(對象鎖)
wait: 讓線程進入等待狀態,讓出cpu的時間片,並釋放監視器所有權,等待其他線程通過notify方法喚醒
生產者與消費者案例代碼示例:
package com.booy;
public class ProducterCustomerDemo {
public static void main(String[] args) {
Food f = new Food();
Producter producter = new Producter(f);
Customer customer = new Customer(f);
Thread t1= new Thread(producter);
Thread t2= new Thread(customer);
t1.start();
t2.start();
}
}
//生產者
class Producter implements Runnable{
private Food food;
public Producter(Food food){
this.food=food;
}
@Override
public void run() {
for (int i = 0; i <10 ; i++) {
if(i%2==0){
food.set("包子豆腐","肉香四溢");
}else {
food.set("炸雞腿","香脆鮮美,外酥裏嫩");
}
}
}
}
//消費者
class Customer implements Runnable{
private Food food;
public Customer(Food food){
this.food=food;
}
@Override
public void run() {
for (int i = 0; i <10 ; i++) {
food.get();
}
}
}
//食物類
class Food{
private String name;
private String desc;
private boolean flag = true;//true表示可以生產,flase表示可以消費
//生產食物
public synchronized void set(String name, String desc){
if(!flag){
try {
this.wait();//進入休眠狀態
} catch (InterruptedException e) {
e.printStackTrace();
}
}
this.name=name;
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
this.desc = desc;
flag = false;
this.notify();//喚醒線程等待中的隨機一個
}
//消費食物
public synchronized void get(){
if(flag){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
try {
Thread.sleep(500);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(name+"-->"+desc);
flag = true;
this.notify();
}
public Food() {}
}
/**
運行結果:
包子豆腐-->肉香四溢
炸雞腿-->香脆鮮美,外酥裏嫩
包子豆腐-->肉香四溢
炸雞腿-->香脆鮮美,外酥裏嫩
包子豆腐-->肉香四溢
炸雞腿-->香脆鮮美,外酥裏嫩
包子豆腐-->肉香四溢
炸雞腿-->香脆鮮美,外酥裏嫩
包子豆腐-->肉香四溢
炸雞腿-->香脆鮮美,外酥裏嫩
*/