生產者與消費者問題


知識點:生產者與消費者問題

 

涉及到的線程間通信的方法

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



運行部分結果截圖:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM