天天看點

Java多線程之——生産者、消費者簡單實作

   生産者與消費者模式是大學課程《作業系統》中較為重要的内容之一。當時隻是囫囵吞棗的了解個大概。其實生産者消費者問題是研究多線程程式時繞不開的經典問題之一,實質上,很多背景服務程式并發控制的基本原理都可以歸納為生産者/消費者模式。

1、問題描述:

         生産者消費者問題(英語:Producer-consumer problem),也稱有限緩沖問題(英語:Bounded-buffer problem),是一個 多線程 同步 問題的經典案例。該問題描述了兩個共享固定大小 緩沖區 的線程--即所謂的"生産者"和"消費者"--在實際運作時會發生的問題。生産者的主要作用是生成一定量的資料放到緩沖區中,然後重複此過程。與此同時,消費者也在緩沖區消耗這些資料。該問題的關鍵就是要保證生産者不會在緩沖區滿時加入資料,消費者也不會在緩沖區中空時消耗資料。

2、Wati()-notify()解決生産者消費問題(配合Synchrnized關鍵字使用)

2.1定義一個公共緩沖區

public class BufferArear{
	private final int MAX_SIZE =100;     //緩沖區可容納最大資源數
        private int num = 10;                // 緩沖區目前資源數目
    
        public synchronized void addObj(){   
    	while(num == MAX_SIZE){
    		try {
				wait();
				System.out.println("目前緩沖區有"+num+"産品,暫停生産");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    		
    	}
    	num++;
    	System.out.println(Thread.currentThread().getName()+"生産了1個,目前緩沖區有"+num+"件産品");
    }
    
    public synchronized void decrease(){
    	while(num == 0){
    		try {
				wait();
				System.out.println("目前緩沖區有"+num+"産品,無産品可消費");
			} catch (InterruptedException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
    		
    	}  
    	num--;
    	System.out.println(Thread.currentThread().getName()+"消費了1個,目前緩沖區有"+num+"件産品");
    }
    
    
    
}
           

2.2生産者程序&消費者程序

package cn.shu.ProducerConsumer;   //生産者程序

public class ConsumeThread implements Runnable {
	PublicResource  pb = null;
	
	public ConsumeThread(PublicResource  pb) {
		// TODO Auto-generated constructor stub
		this.pb  = pb;  
	}
	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			pb.decrease();
		}
		
	}
	

}
           
package cn.shu.ProducerConsumer;  //消費者程序


public class ConsumeThread implements Runnable {
	PublicResource  pb = null;
	
	public ConsumeThread(PublicResource  pb) {
		// TODO Auto-generated constructor stub
		this.pb  = pb;  
	}
	@Override
	public void run() {
		for (int i = 0; i < 10; i++) {
			pb.decrease();
		}
		
	}
	


}
           
2.3 測試類
package cn.shu.ProducerConsumer;

public class Test {
     public static void main(String[] args) {
    	 PublicResource  pb =new PublicResource();
		new Thread(new ProduceThread(pb),"生産者1").start();
		new Thread(new ConsumeThread(pb),"消費者1").start();
		new Thread(new ProduceThread(pb),"生産者2").start();
		new Thread(new ProduceThread(pb),"生産者3").start();
		new Thread(new ConsumeThread(pb),"消費者1").start();
		
	}
}