生產者和消費者模式

生產者-消費者(producer-consumer)問題,也稱作有界緩衝區(bounded-buffer)問題,兩個進程共享一個公共的固定大小的緩衝區。其中一個是生產者,用於將消息放入緩衝區;另外一個是消費者,用於從緩衝區中取出消息。問題出現在當緩衝區已經滿了,而此時生產者還想向其中放入一個新的數據項的情形,其解決方法是讓生產者此時進行休眠,等待消費者從緩衝區中取走了一個或者多個數據後再去喚醒它。同樣地,當緩衝區已經空了,而消費者還想去取消息,此時也可以讓消費者進行休眠,等待生產者放入一個或者多個數據時再喚醒它。

一,首先定義公共資源類,其中的變量number是保存的公共數據。並且定義兩個方法,增加number的值和減少number的值。由於多線程的原因,必須加上synchronized關鍵字,注意while判斷的條件。

Java代碼  收藏代碼
  1. /** 
  2.  * 公共資源類 
  3.  */  
  4. public class PublicResource {  
  5.     private int number = 0;  
  6.   
  7.     /** 
  8.      * 增加公共資源 
  9.      */  
  10.     public synchronized void increace() {  
  11.         while (number != 0) {  
  12.             try {  
  13.                 wait();  
  14.             } catch (InterruptedException e) {  
  15.                 e.printStackTrace();  
  16.             }  
  17.         }  
  18.         number++;  
  19.         System.out.println(number);  
  20.         notify();  
  21.     }  
  22.   
  23.     /** 
  24.      * 減少公共資源 
  25.      */  
  26.     public synchronized void decreace() {  
  27.         while (number == 0) {  
  28.             try {  
  29.                 wait();  
  30.             } catch (InterruptedException e) {  
  31.                 e.printStackTrace();  
  32.             }  
  33.         }  
  34.         number--;  
  35.         System.out.println(number);  
  36.         notify();  
  37.     }  
  38. }  
 

二,分別定義生產者線程和消費者線程,並模擬多次生產和消費,即增加和減少公共資源的number值

Java代碼  收藏代碼
  1. /** 
  2.  * 生產者線程,負責生產公共資源 
  3.  */  
  4. public class ProducerThread implements Runnable {  
  5.     private PublicResource resource;  
  6.   
  7.     public ProducerThread(PublicResource resource) {  
  8.         this.resource = resource;  
  9.     }  
  10.   
  11.     @Override  
  12.     public void run() {  
  13.         for (int i = 0; i < 10; i++) {  
  14.             try {  
  15.                 Thread.sleep((long) (Math.random() * 1000));  
  16.             } catch (InterruptedException e) {  
  17.                 e.printStackTrace();  
  18.             }  
  19.             resource.increace();  
  20.         }  
  21.     }  
  22. }  
  23. /** 
  24.  * 消費者線程,負責消費公共資源 
  25.  */  
  26. public class ConsumerThread implements Runnable {  
  27.     private PublicResource resource;  
  28.   
  29.     public ConsumerThread(PublicResource resource) {  
  30.         this.resource = resource;  
  31.     }  
  32.   
  33.     @Override  
  34.     public void run() {  
  35.         for (int i = 0; i < 10; i++) {  
  36.             try {  
  37.                 Thread.sleep((long) (Math.random() * 1000));  
  38.             } catch (InterruptedException e) {  
  39.                 e.printStackTrace();  
  40.             }  
  41.             resource.decreace();  
  42.         }  
  43.     }  
  44. }  
 

三,模擬多個生產者和消費者操作公共資源的情形,結果須保證是在允許的範圍內。

Java代碼  收藏代碼
  1. public class ProducerConsumerTest {  
  2.     public static void main(String[] args) {  
  3.         PublicResource resource = new PublicResource();  
  4.         new Thread(new ProducerThread(resource)).start();  
  5.         new Thread(new ConsumerThread(resource)).start();  
  6.         new Thread(new ProducerThread(resource)).start();  
  7.         new Thread(new ConsumerThread(resource)).start();  
  8.         new Thread(new ProducerThread(resource)).start();  
  9.         new Thread(new ConsumerThread(resource)).start();  
  10.     }  
  11. }  
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章