生產者和消費者問題:管程法
阿新 • • 發佈:2022-04-11
管程法是用於解決執行緒之間通訊與執行緒不安全的一種解決辦法,典型的生產者與消費者問題可以通過管程法進行解決,特點是建立一個消費者和生產者發生通訊的緩衝區,進而實現解決執行緒通訊
實現思路:
- 建立四個類,分別用於定義消費者、生產者、產品、快取區,四個類都有各自負責的事情
- Productor類需要實現生產產品,通過Store store定義一個store型別的資料,通過for迴圈模擬產品生產,再建立一個productor物件,通過store.push方法把產品編號傳進去
- Consumer類負責消費產品,它也需要一個倉庫物件store,因為它需要消費,所以for迴圈每執行一次產品數量-1
- product類實現的是生產的產品,給這個產品一個標記
- store是生產者和消費者之間連線的橋樑,相當於肯德基的前臺,它需要負責的東西很多,首先要負責溝通後廚,如果生產的產品大於十個就讓生產者停止生產,使用wait()方法,如果沒有產品,就喚醒生產者繼續生產,通過notifyall()方法喚醒生產者,還要有一個儲物櫃用於儲存生產好的商品
import static jdk.nashorn.internal.objects.NativeArray.push; public class TestPC { public static void main(String[] args) { Store store=new Store(); //建立一個倉庫物件 Productor productor = new Productor(store); //建立一個生產者物件並獲取倉庫物件 Consumer consumer = new Consumer(store); //建立一個消費者物件並獲取倉庫物件 new Thread(productor).start();//執行緒進入就緒狀態 new Thread(consumer).start(); //執行緒就緒就緒狀態 } } //生產者 class Productor implements Runnable{ Store store; //生產者需要獲取倉庫物件用以儲存產品 Productor(Store store){ this.store=store; } @Override public void run() { for (int i = 1; i <= 100; i++) { //將生產產品存入倉庫 Product product=new Product(i); store.push(product); } } } //消費者 class Consumer implements Runnable{ Store store; Consumer(Store store){ this.store=store; } @Override public void run() { for (int i = 1; i <= 100; i++){ //取出一個產品 store.pop(); } } } //產品 class Product{ //給產品一個id屬性 int id; public Product(int id){ this.id=id; } } //倉庫快取區 class Store{ Product []products=new Product[10];//定義一個容納10個產品的物件陣列 static int count=0;//倉庫產品數量計數,初始為0 public synchronized void push(Product product){ //判斷倉庫是否已滿,若滿則呼叫wait()方法令執行緒停止,使生產者停止產品的生產 if (count>=10) { try { wait();//執行緒等待 } catch (InterruptedException e) { e.printStackTrace(); } } products[count]=product; count++; System.out.println("生產者生產了第"+product.id+"個產品"); this.notifyAll();//喚醒所有執行緒 } public synchronized void pop(){ //判斷倉庫是否存在產品,若無則呼叫wait()方法令執行緒停止,使消費者停止產品的獲取 if (count==0){ try { wait();//執行緒等待 } catch (InterruptedException e) { e.printStackTrace(); } } count--; Product product=products[count]; System.out.println("消費者消費了第"+product.id+"個產品"); this.notifyAll();//喚醒所有執行緒 } }