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