導航:首頁 > 編程語言 > java消費者生產者模式

java消費者生產者模式

發布時間:2024-09-03 10:27:44

Ⅰ 銀行運行模擬 設計一個Java應用程序,模擬顧客到銀行存取款的現象。 謝謝

使用的生產者和消費者模型具有如下特點:

(1)本實驗的多個緩沖區不是環形循環的,也不要求按順序訪問。生產者可以把產品放到目前某一個空緩沖區中。

(2)消費者只消費指定生產者的產品。

(3)在測試用例文件中指定了所有的生產和消費的需求,只有當共享緩沖區的數據滿足了所有關於它的消費需求後,此共享緩沖區才可以作為空閑空間允許新的生產者使用。

(4)本實驗在為生產者分配緩沖區時各生產者間必須互斥,此後各個生產者的具體生產活動可以並發。而消費者之間只有在對同一產品進行消費時才需要互斥,同時它們在消費過程結束時需要判斷該消費對象是否已經消費完畢並清除該產品。

Windows 用來實現同步和互斥的實體。在Windows 中,常見的同步對象有:信號量(Semaphore)、

互斥量(Mutex)、臨界段(CriticalSection)和事件(Event)等。本程序中用到了前三個。使用這些對象都分

為三個步驟,一是創建或者初始化:接著請求該同步對象,隨即進入臨界區,這一步對應於互斥量的

上鎖;最後釋放該同步對象,這對應於互斥量的解鎖。這些同步對象在一個線程中創建,在其他線程

中都可以使用,從而實現同步互斥。當然,在進程間使用這些同步對象實現同步的方法是類似的。

1.用鎖操作原語實現互斥

為解決進程互斥進人臨界區的問題,可為每類臨界區設置一把鎖,該鎖有打開和關閉兩種狀態,進程執行臨界區程序的操作按下列步驟進行:

①關鎖。先檢查鎖的狀態,如為關閉狀態,則等待其打開;如已打開了,則將其關閉,繼續執行步驟②的操作。

②執行臨界區程序。

③開鎖。將鎖打開,退出臨界區。

2.信號量及WAIT,SIGNAL操作原語

信號量的初值可以由系統根據資源情況和使用需要來確定。在初始條件下信號量的指針項可以置為0,表示隊列為空。信號量在使用過程中它的值是可變的,但只能由WAIT,SIGNAL操作來改變。設信號量為S,對S的WAIT操作記為WAIT(S),對它的SIGNAL操作記為SIGNAL(S)。

WAIT(S):順序執行以下兩個動作:

①信號量的值減1,即S=S-1;

②如果S≥0,則該進程繼續執行;

如果 S(0,則把該進程的狀態置為阻塞態,把相應的WAITCB連人該信號量隊列的末尾,並放棄處理機,進行等待(直至其它進程在S上執行SIGNAL操作,把它釋放出來為止)。

SIGNAL(S):順序執行以下兩個動作

①S值加 1,即 S=S+1;

②如果S)0,則該進程繼續運行;

如果S(0則釋放信號量隊列上的第一個PCB(既信號量指針項所指向的PCB)所對應的進程(把阻塞態改為就緒態),執行SIGNAL操作的進程繼續運行。

在具體實現時注意,WAIT,SIGNAL操作都應作為一個整體實施,不允許分割或相互穿插執行。也就是說,WAIT,SIGNAL操作各自都好像對應一條指令,需要不間斷地做下去,否則會造成混亂。

從物理概念上講,信號量S)時,S值表示可用資源的數量。執行一次WAIT操作意味著請求分配一個單位資源,因此S值減1;當S<0時,表示已無可用資源,請求者必須等待別的進程釋放了該類資源,它才能運行下去。所以它要排隊。而執行一次SIGNAL操作意味著釋放一個單位資源,因此S值加1;若S(0時,表示有某些進程正在等待該資源,因而要把隊列頭上的進程喚醒,釋放資源的進程總是可以運行下去的。

---------------
/**
* 生產者
*
*/
public class Procer implements Runnable{
private Semaphore mutex,full,empty;
private Buffer buf;
String name;
public Procer(String name,Semaphore mutex,Semaphore full,Semaphore empty,Buffer buf){
this.mutex = mutex;
this.full = full;
this.empty = empty;
this.buf = buf;
this.name = name;
}
public void run(){
while(true){
empty.p();
mutex.p();
System.out.println(name+" inserts a new proct into "+buf.nextEmptyIndex);
buf.nextEmptyIndex = (buf.nextEmptyIndex+1)%buf.size;
mutex.v();
full.v();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}

---------------
/**
* 消費者
*
*/
public class Customer implements Runnable{
private Semaphore mutex,full,empty;
private Buffer buf;
String name;
public Customer(String name,Semaphore mutex,Semaphore full,Semaphore empty,Buffer buf){
this.mutex = mutex;
this.full = full;
this.empty = empty;
this.buf = buf;
this.name = name;
}
public void run(){
while(true){
full.p();
mutex.p();
System.out.println(name+" gets a proct from "+buf.nextFullIndex);
buf.nextFullIndex = (buf.nextFullIndex+1)%buf.size;
mutex.v();
empty.v();
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
-------------------------
/**
* 緩沖區
*
*/
public class Buffer{
public Buffer(int size,int nextEmpty,int nextFull){
this.nextEmptyIndex = nextEmpty;
this.nextFullIndex = nextFull;
this.size = size;
}
public int size;
public int nextEmptyIndex;
public int nextFullIndex;
}
-----------------
/**
* 此類用來模擬信號量
*
*/
public class Semaphore{
private int semValue;
public Semaphore(int semValue){
this.semValue = semValue;
}
public synchronized void p(){
semValue--;
if(semValue<0){
try {
this.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public synchronized void v(){
semValue++;
if(semValue<=0){
this.notify();
}
}
}
------------------------
public class Test extends Thread
{
public static void main(String[] args)
{
Buffer bf=new Buffer(10,0,0);
Semaphore mutex=new Semaphore(1);
Semaphore full=new Semaphore(0);
Semaphore empty=new Semaphore(10);
//new Thread(new Procer("p001",mutex,full,empty,bf)).start();
Procer p=new Procer("p001",mutex,full,empty,bf);
new Thread(new Procer("p002",mutex,full,empty,bf)).start();
new Thread(new Procer("p003",mutex,full,empty,bf)).start();
new Thread(new Procer("p004",mutex,full,empty,bf)).start();
new Thread(new Procer("p005",mutex,full,empty,bf)).start();
try{
sleep(3000);
}
catch(Exception ex)
{
ex.printStackTrace();
}
new Thread(new Customer("c001",mutex,full,empty,bf)).start();
new Thread(new Customer("c002",mutex,full,empty,bf)).start();
new Thread(new Customer("c003",mutex,full,empty,bf)).start();
new Thread(new Customer("c004",mutex,full,empty,bf)).start();
new Thread(new Customer("c005",mutex,full,empty,bf)).start();
}
}
--------------------------------------------

Ⅱ 生產者和消費者模型

生產者和消費者模型詳解


在Java多線程編程中,生產者和消費者模型是一種關鍵的設計模式,它通過優化CPU多線程性能,提升系統數據處理速度,降低系統負載,增強程序效率和穩定性,同時促進模塊間的解耦。


核心概念是,生產者和消費者通過緩沖區進行間接交互:生產者負責生成數據並存入,消費者則從緩沖區取出處理。流程圖顯示了這一基本運作方式。該模型的典型特點包括高效的數據流管理和線程間的協作。


這種模型在Java線程池任務執行框架和消息中間件如rabbitMQ中廣泛應用,掌握它對開發者至關重要。以下是實際應用的案例:



在多生產者和消費者情況下,正確使用ReentrantLock和Condition的Condition實例,配合signalAll()方法,可以防止程序假死,確保並發操作的順利進行。


總結來說,通過靈活運用生產者和消費者模型,我們可以優化系統性能,避免常見問題。掌握這一模式對於高效編程至關重要。

閱讀全文

與java消費者生產者模式相關的資料

熱點內容
哪些php網站有哪些東西 瀏覽:789
pdf文件轉word文件怎麼打開 瀏覽:808
許可權的文件夾圖標 瀏覽:827
智能加密門卡怎麼弄在手機 瀏覽:501
程序員改需求 瀏覽:111
android環信圖片 瀏覽:134
ees演算法具有什麼特點 瀏覽:768
安卓手機如何弄戀愛日記 瀏覽:624
android連接webservice 瀏覽:221
對於簡單的加密和編碼方法 瀏覽:334
XC8編譯結果不同 瀏覽:217
氣體隔膜壓縮機 瀏覽:587
新的電腦文件夾打開為什麼是空的 瀏覽:821
製冷壓縮機壽命 瀏覽:734
androidlistview按下顏色 瀏覽:194
單片機實驗報告蜂鳴器 瀏覽:10
農業量地用什麼app 瀏覽:11
python構造時間 瀏覽:843
頁面加密不能復制 瀏覽:680
什麼app可以看美劇無刪美劇 瀏覽:845