Java多執行緒之——生產者、消費者簡單實現
阿新 • • 發佈:2019-02-04
生產者與消費者模式是本科課程《作業系統》中較為重要的內容之一。當時只是囫圇吞棗的理解個大概。其實生產者消費者問題是研究多執行緒程式時繞不開的經典問題之一,實質上,很多後臺服務程式併發控制的基本原理都可以歸納為生產者/消費者模式。
/**
*定義了一個公共緩衝區類,這個類提供了可容納最大資源數,生產資源方法,消費資源方法。
*/
2.3 測試類
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();
}
}