網(wǎng)站首頁 編程語言 正文
如果把生產(chǎn)消費(fèi)想像成自動(dòng)流水生產(chǎn)線的話,生產(chǎn)就是流水線的物料,消費(fèi)就是某種設(shè)備對物料進(jìn)行加工的行為,流水線就是隊(duì)列。
現(xiàn)在,要寫一個(gè)體現(xiàn)生產(chǎn)消費(fèi)模式的泛型幫助類,比如叫ProducerConsumer<T>。
該類肯定會(huì)維護(hù)一個(gè)有關(guān)生產(chǎn)、物料的Queue<T>類型的字段,還存在一個(gè)有關(guān)消費(fèi)、Action<T>類型的字段。
在ProducerConsumer類的構(gòu)造函數(shù)中,為Action<T>類型的字段賦值,并開啟后臺(tái)有關(guān)消費(fèi)的線程。
ProducerConsumer類肯定存在一個(gè)進(jìn)隊(duì)列的方法,并且要保證在多線程情況下,同一時(shí)間只有一個(gè)生產(chǎn)或物料進(jìn)入隊(duì)列。
ProducerConsumer類還存在一個(gè)有關(guān)消費(fèi)的方法,并且保證在多線程情況下,同一時(shí)間只有一個(gè)生產(chǎn)或物料出列,并消費(fèi)它。
另外,在生產(chǎn)或物料在出隊(duì)列的時(shí)候,可能會(huì)出現(xiàn)隊(duì)列中暫時(shí)沒有生產(chǎn)或物料的情況,這時(shí)候我們希望線程阻塞一下,這需要通過AutoResetEvent實(shí)現(xiàn)。AutoResetEvent的大致原理是:當(dāng)生產(chǎn)或物料進(jìn)入隊(duì)列的時(shí)候需要告訴AutoResetEvent一下,當(dāng)隊(duì)列中暫時(shí)沒有生產(chǎn)或物料的時(shí)候,也需要告訴AutoResetEvent,讓它來阻塞線程。
//有關(guān)生產(chǎn)消費(fèi)的泛型類
public class ProducerConsumer<T>
{
//用來存儲(chǔ)生產(chǎn)者的隊(duì)列
private readonly Queue<T> queue = new Queue<T>();
//鎖
private readonly object queueLocker = new object();
//消費(fèi)行為
private readonly Action<T> consumerAction;
//出列的時(shí)候需要檢查隊(duì)列中是否有元素,如果沒有,需要阻塞
private readonly AutoResetEvent queueWaitHandle = new AutoResetEvent(false);
public ProducerConsumer(Action<T> consumerAction)
{
if (consumerAction == null)
{
throw new ArgumentNullException("consumerAction");
}
this.consumerAction = consumerAction;
//后臺(tái)開啟一個(gè)線程開始消費(fèi)生產(chǎn)者
new Thread(this.ConsumeItems){IsBackground = true}.Start();
}
//進(jìn)列
public void Enqueue(T item)
{
//確保同一時(shí)間只有一個(gè)生產(chǎn)者進(jìn)列
lock (queueLocker)
{
queue.Enqueue(item);
//每次進(jìn)列都要設(shè)置AutoResetEvent事件
this.queueWaitHandle.Set();
}
}
//消費(fèi)動(dòng)作
private void ConsumeItems()
{
while (true)
{
T nextItem = default(T);
//標(biāo)志,確認(rèn)隊(duì)列中的生產(chǎn)者是否存在
bool doesItemExist;
//確保同一時(shí)間只有一個(gè)生產(chǎn)者出列
lock (this.queueLocker)
{
//先確認(rèn)隊(duì)列中的生產(chǎn)者是否存在
doesItemExist = this.queue.Count > 0;
if (doesItemExist)
{
nextItem = this.queue.Dequeue();
}
}
//如果生產(chǎn)者存在,才消費(fèi)生產(chǎn)者
if (doesItemExist)
{
this.consumerAction(nextItem);
}
else//否則的話,再等等下一個(gè)隊(duì)列中的生產(chǎn)者
{
this.queueWaitHandle.WaitOne();
}
}
}
}
客戶端,針對多線程情形。
class Program
{
static void Main(string[] args)
{
//實(shí)例化一個(gè)int類型的生產(chǎn)消費(fèi)實(shí)例
var producerConsumer = new ProducerConsumer<int>(i => Console.WriteLine("正在消費(fèi)" + i));
Random random = new Random();
//開啟進(jìn)隊(duì)列線程
var t1 = new Thread(() =>
{
for (int i = 0; i < 100; i++)
{
producerConsumer.Enqueue(i);
Thread.Sleep(random.Next(0,5));
}
});
var t2 = new Thread(() =>
{
for (int i = 0; i > -100; i--)
{
producerConsumer.Enqueue(i);
Thread.Sleep(random.Next(0, 5));
}
});
t1.Start();
t2.Start();
t1.Join();
t2.Join();
Thread.Sleep(50);
Console.ReadKey();
}
}
原文鏈接:https://www.cnblogs.com/darrenji/p/4523674.html
相關(guān)推薦
- 2023-10-14 關(guān)于Smartbi配置Sql Server數(shù)據(jù)源調(diào)用HTTP請求
- 2023-03-20 Redis使用Bitmap的方法實(shí)現(xiàn)_Redis
- 2022-11-08 C語言實(shí)現(xiàn)時(shí)間處理工具的示例代碼_C 語言
- 2023-03-25 Python?self參數(shù)詳細(xì)介紹_python
- 2024-03-19 Linux中 find 命令詳解
- 2023-02-12 PyCharm軟件無法安裝lxml庫的問題及解決_python
- 2022-03-29 docker?安裝?zeppeline的操作_docker
- 2022-05-16 C++實(shí)現(xiàn)圖書管理系統(tǒng)源碼_C 語言
- 最近更新
-
- window11 系統(tǒng)安裝 yarn
- 超詳細(xì)win安裝深度學(xué)習(xí)環(huán)境2025年最新版(
- Linux 中運(yùn)行的top命令 怎么退出?
- MySQL 中decimal 的用法? 存儲(chǔ)小
- get 、set 、toString 方法的使
- @Resource和 @Autowired注解
- Java基礎(chǔ)操作-- 運(yùn)算符,流程控制 Flo
- 1. Int 和Integer 的區(qū)別,Jav
- spring @retryable不生效的一種
- Spring Security之認(rèn)證信息的處理
- Spring Security之認(rèn)證過濾器
- Spring Security概述快速入門
- Spring Security之配置體系
- 【SpringBoot】SpringCache
- Spring Security之基于方法配置權(quán)
- redisson分布式鎖中waittime的設(shè)
- maven:解決release錯(cuò)誤:Artif
- restTemplate使用總結(jié)
- Spring Security之安全異常處理
- MybatisPlus優(yōu)雅實(shí)現(xiàn)加密?
- Spring ioc容器與Bean的生命周期。
- 【探索SpringCloud】服務(wù)發(fā)現(xiàn)-Nac
- Spring Security之基于HttpR
- Redis 底層數(shù)據(jù)結(jié)構(gòu)-簡單動(dòng)態(tài)字符串(SD
- arthas操作spring被代理目標(biāo)對象命令
- Spring中的單例模式應(yīng)用詳解
- 聊聊消息隊(duì)列,發(fā)送消息的4種方式
- bootspring第三方資源配置管理
- GIT同步修改后的遠(yuǎn)程分支