第五章 生產者消費者模式

2021-08-27 17:59:12 字數 2999 閱讀 8330

producer 生產者,產生資料的執行緒

consumer 消費者,使用資料的執行緒

【示例程式】

桌子上最多可放置3個蛋糕

如果桌子上已經放滿3個蛋糕時糕點師還要再放置蛋糕,必須等到桌子上空出位置。

客人(eaterthread)取桌子上的蛋糕吃

客人按蛋糕被放置到桌子上的順序來取蛋糕

當桌子上1個蛋糕都沒有時,客人若取蛋糕,必須等到桌子上新放置了蛋糕

名字說明

main

測試程式行為的類

makerthread

表示糕點師的類

eaterthread

表示客人的類

table

表示桌子的類

main類

建立乙個桌子例項並啟動表示糕點師和客人的執行緒。makerthread和eaterthread的建構函式中傳入的數字只是用來作為隨機數的種子,數值本身沒有實際意義。

public class main 

}

makerthread類

用於製作蛋糕並將其放置到桌子上。無線迴圈執行「製作蛋糕,放置在桌子上」。

public class makerthread extends thread

public void run()

}catch(interruptedexception e) {}

}public static synchronized int nextid()

}

eaterthread類

用於表示從桌子上取蛋糕吃的客人。無限迴圈執行「從桌子上取蛋糕,吃蛋糕」。

public class eaterthread extends thread 

public void run()

}catch(interruptedexception e){}

}}

table類

用於表示放置蛋糕的桌子。可防止的蛋糕個數通過建構函式來指定。

public class table 

//放置蛋糕

public synchronized void put(string cake) throws interruptedexception

buffer[tail]=cake;

tail = (tail+1)%buffer.length;

count++;

notifyall();

}//拿去蛋糕

public synchronized string take() throws interruptedexception

string cake = buffer[head];

head=(head+1)%buffer.length;

count--;

notifyall();

system.out.println(thread.currentthread().getname()+" takes "+cake);

return cake;

}}

【producer-consumer模式中登場的角色】

1.data

data角色由producer角色生成,供consumer使用。

2.producer生產者

producer角色生成data角色,並將其傳遞給channel角色。

3.consumer角色

consumer角色從channel角色獲取data角色並使用。

4.channel通道

channel角色保管從producer角色獲取的data角色,還會響應consumer角色的請求,傳遞data角色。

【拓展思路的要點】守護安全性的channel角色(可復用性)

在producer-consumer模式中,承擔安全守護責任的是channel角色。channel角色執行執行緒間的互斥處理,確保生產者角色正確地將data角色傳遞給consumer角色。

【延伸閱讀】理解interruptedexception異常

加了throws interruptedexception的方法可能會發費時間,但可以取消。

1.花費時間的方法

執行緒執行wait方法,會進入等待佇列,等待被notify/notifyall。在等待期間,執行緒是不執行的,但需要花費時間來等待被notify/notifyall。

執行緒執行sleep方法後,會暫停執行(暫停多長時間由引數指定)。

執行緒執行join方法後,會等待指定執行緒終止。該方法需要花費時間,來等待指定執行緒終止。

2.sleep和interru方法

假設執行緒alice執行下面這條語句,使用sleep方法暫停了執行。

thread.sleep(***);

由於執行緒alice正處於暫停狀態,所以只能由其他執行緒來執行取消操作。

alice.interrupted();

變數alice裡儲存著與執行緒alice對應的thread例項。

這裡使用的interrrupt方法是thread類的例項方法。當執行interrupt時,執行緒並不需要獲取thread例項的鎖。任何執行緒任何時候都可以呼叫其他執行緒的interrupt方法。

interrupt方法被呼叫後,正在sleep的執行緒會終止暫停狀態,丟擲interruptedexception異常。此處丟擲異常的執行緒是alice。

這樣執行緒alice的控制器就會轉移到捕捉該異常的catch語句塊中。

3.wait個interrupt方法

執行緒alice使用wait進行等待時,與使用sleep暫停執行時一樣,也是可以取消的。當使用interrupt方法時,該操作意即告訴正在wait的執行緒不用再等待notify/notifyall了,從等待佇列裡出來吧。

在wait的情況下,需要注意鎖的問題。執行緒在進入等待佇列時,已經釋放了鎖。當正在wait的執行緒被呼叫interrupt方法時,該執行緒會在重新獲取鎖之後丟擲interruptedexception異常。在獲取鎖之前,執行緒不會丟擲interruptedexception異常。

生產者消費者 生產者與消費者模式

一 什麼是生產者與消費者模式 其實生產者與消費者模式就是乙個多執行緒併發協作的模式,在這個模式中呢,一部分執行緒被用於去生產資料,另一部分執行緒去處理資料,於是便有了形象的生產者與消費者了。而為了更好的優化生產者與消費者的關係,便設立乙個緩衝區,也就相當於乙個資料倉儲,當生產者生產資料時鎖住倉庫,不...

生產者 消費者模式

一 我哥們把資料存入redis快取區 生產者 二 我從緩衝器取資料,並作處理!消費者 詳細 如下 取訂單並判斷 redis new redis conn flag redis connect redis translate usefull host,redis translate usefull p...

生產者消費者模式

常見場景 某個模組負責產生資料,這些資料由另乙個模組來負責處理。產生資料的模組,就形象地稱為生產者 而處理資料的模組,就稱為消費者。該模式還需要有乙個緩衝區處於生產者和消費者之間,作為乙個中介。生產者把資料放入緩衝區,而消費者從緩衝區取出資料 緩衝區作用 1.解耦,生產者和消費者只依賴緩衝區,而不互...