知識點:生產者與消費者問題
涉及到的線程間通信的方法
wait():當前線程掛起並放棄CPU,同步資源,使別的線程可訪問並修改共享資源,當前線程排隊等候再次對資源訪問
notify():喚醒正在排隊等待同步資源的線程中優先級最高者結束等待
notifyAll():喚醒正在排隊等待資源的所有線程結束等待
場景:
生產者(Producer)生產產品,送到店員(Clerk)那里,消費者(Customer)從店員那里取走產品,店員只能持有一定數量的產品(如:20),如果店員那里已經有了20個產品,店員會通知生產者停一下(wait()),店中有空位置放產品時,通知生產者繼續生產,如果店員那里沒有產品了,會通知消費者等一下,店中有產品了,通知消費者繼續消費。
實例:
class Clerk { //店員
int product;
public synchronized void AddProduct(){
if(product<20){ //產品小於20時,繼續生產產品
product++;
System.out.println(Thread.currentThread().getName()+"生產了第"+product+"個產品");
notifyAll(); //產品為0時,消費者等待,產品product++,有產品了,通知消費者繼續消費
}else {
try {
wait(); //產品大於等於20時,生產者等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void ConsumeProduct(){
if(product>0){ //產品大於0時,消費者取走產品
System.out.println(Thread.currentThread().getName()+"消費了第"+product+"個產品");
product--;
notifyAll(); //產品為20時,生產者等待,產品product--,有產品的空位置時,通知生產者繼續生產
}else {
try {
wait(); //產品為0時,消費者等待
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
class Producer implements Runnable{//生產者
Clerk clerk;
public Producer(Clerk clerk){
this.clerk=clerk;
}
@Override
public void run() {
while (true){
clerk.AddProduct();
}
}
}
class Consumer implements Runnable{ //消費者
Clerk clerk;
public Consumer(Clerk clerk){
this.clerk=clerk;
}
@Override
public void run() {
while (true) {
clerk.ConsumeProduct();
}
}
}
測試類
public class Test {
public static void main(String[] args) {
Clerk clerk=new Clerk();
Producer p1=new Producer(clerk);
Consumer c1=new Consumer(clerk);
Thread th1=new Thread(p1);
Thread th2=new Thread(c1);
th1.setName("生產者:");
th2.setName("消費者:");
th1.start();
th2.start();
}
}
運行部分結果截圖:
