我正在尝试实现支持消费者超时的并发 生产环境 者 - 消费者集合(多个 生产环境 者和消费者) .

现在实际的集合非常复杂(不幸的是,在System.Collections.Concurrent中没有任何工作),但我在这里有一个最小的示例来演示我的问题(看起来有点像 BlockingCollection ) .

public sealed class ProducerConsumerQueueDraft

{

private readonly Queue queue = new Queue();

private readonly object locker = new object();

public void Enqueue(T item)

{

lock (locker)

{

queue.Enqueue(item);

/* This "optimization" is broken, as Nicholas Butler points out.

if(queue.Count == 1) // Optimization

*/

Monitor.Pulse(locker); // Notify any waiting consumer threads.

}

}

public T Dequeue(T item)

{

lock (locker)

{

// Surprisingly, this needs to be a *while* and not an *if*

// which is the core of my problem.

while (queue.Count == 0)

Monitor.Wait(locker);

return queue.Dequeue();

}

}

// This isn't thread-safe, but is how I want TryDequeue to look.

public bool TryDequeueDesired(out T item, TimeSpan timeout)

{

lock (locker)

{

if (queue.Count == 0 && !Monitor.Wait(locker, timeout))

{

item = default(T);

return false;

}

// This is wrong! The queue may be empty even though we were pulsed!

item = queue.Dequeue();

return true;

}

}

// Has nasty timing-gymnastics I want to avoid.

public bool TryDequeueThatWorks(out T item, TimeSpan timeout)

{

lock (locker)

{

var watch = Stopwatch.StartNew();

while (queue.Count == 0)

{

var remaining = timeout - watch.Elapsed;

if (!Monitor.Wait(locker, remaining < TimeSpan.Zero ? TimeSpan.Zero : remaining))

{

item = default(T);

return false;

}

}

item = queue.Dequeue();

return true;

}

}

}

这个想法很简单:找到空队列的消费者等待发信号通知,并且生成者(注意:不是 PulseAll ,这将是低效的)他们通知他们等待的项目 .

当调用Pulse的线程释放锁定时,就绪队列中的下一个线程(不一定是脉冲线程)获取锁定 .

这意味着消费者线程C1可以被 生产环境 者线程唤醒以消耗一个项目,但是另一个消费者线程C2可以在C1有机会重新获取它之前获取锁定并消耗该项目,留下C1与给予控制时的空队列 .

这意味着如果队列确实非空,我必须在每个脉冲上防御性地检查消费者代码,如果不是这种情况,则返回并空手等待 .

我的主要问题是它效率低下 - 线程可能会被唤醒以进行工作,然后立即返回等待 . 这样做的一个相关结果是,当它应该是优雅的时候实现具有超时的 TryDequeue 是不必要的困难和低效的(参见 TryDequeueThatWorks )(参见 TryDequeueDesired ) .

How can I twist Monitor.Pulse to do what I want? Alternatively, is there another synchronization primitive that does? Is there a more efficient and/or elegant way to implement a TryDequeue timeout than what I have done?

仅供参考,这是一个测试,用于演示我所需解决方案的问题:

var queue = new ProducerConsumerQueueDraft();

for (int consumer = 0; consumer < 3; consumer++)

new Thread(() =>

{

while (true)

{

int item;

// This call should occasionally throw an exception.

// Switching to queue.TryDequeueThatWorks should make

// the problem go away.

if (queue.TryDequeueDesired(out item, TimeSpan.FromSeconds(1)))

{

// Do nothing.

}

}

}).Start();

Thread.Sleep(1000); // Let consumers get up and running

for (int itemIndex = 0; itemIndex < 50000000; itemIndex++)

{

queue.Enqueue(0);

}

java 超时集合_确定性监视器脉冲/等待并在 生产环境 者 - 消费者集合中实现超时...相关推荐

  1. java开发平板_用Android平板来写代码 - Termux 环境搭建

    之前入了一个洋垃圾 华硕P00I,我对这款平板的第一印象是:屏幕好,电池耐用.如果忽略后压屏的缺点,还是很有性价比的. 除了平时看小说.PDF.PPT.视频,作为一个程序员(还没毕业),想着是否可以更 ...

  2. java 打包 配置文件_有关打包成可执行jar包后引用jar包中配置文件问题

    一 问题由来 有时候我们做一些项目时,需要将一些配置信息写入配置文件中,以供调用.比如说这样: 如果我们需要在Demo.java中读取config.txt这个文件中的配置信息,在这种工程目录下是可以使 ...

  3. java ean13 条形码_【教程】Spire.Barcode 教程:如何在C#中创建EAN-13条码

    基于UPC-A标准的EAN-13在世界范围内用于标记零售商品. 13位EAN-13号码由四部分组成: 国家代码 - 2或3位数字 制造商代码 - 5至7位数字 产品代码 - 3至5位数字 检查数字 - ...

  4. java mvp模式_什么是mvp开发模式?(下面就对Android中MVP做一些阐述)

    MVP作为一种MVC的演化版本在Android开发中受到了越来越多的关注.值得注意的是,MVP不像JavaEE有着SSH这三个成熟框架支持推动着,所以在运用MVP时一定要做好自己的理解,并且尽量预知自 ...

  5. java生产问题快速定位_生产环境如何快速跟踪、分析、定位问题-Java

    我相信做技术的都会遇到过这样的问题,生产环境服务遇到宕机的情况下如何去分析问题?比如说JVM内存爆掉.CPU持续高位运行.线程被夯住或线程deadlocks,面对这样的问题,如何在生产环境第一时间跟踪 ...

  6. java 分班_大家给我介绍下马上学校就要分班了不知道去JAVA班,还是.NET 爱问知识人...

    Java是一个广泛使用的网络编程语言 ,它是一种新的计算概念. 首先 ,作为一种程序设计语言 ,它简单.面向对象.不依赖于机器的结构.具有可移植性.鲁棒性.安全性.并且提供了并发的机制.具有很高的性能 ...

  7. java开发的微信公众号服务端生产环境中的两个大坑

    摘要: 我们开发的公众号,由于将功能开发完毕后,未对服务进行压力测试,因此用到的组件中的参数值全是默认的,服务上线后一段时间运行得倒没什么问题,随着服务得访问量增加,一些多线程并发的问题就逐步暴露出来 ...

  8. SpringCloud服务消费者第一次调用出现超时问题的解决方案

    SpringCloud服务消费者第一次调用出现超时问题的解决方案 参考文章: (1)SpringCloud服务消费者第一次调用出现超时问题的解决方案 (2)https://www.cnblogs.co ...

  9. java 监视锁_【转载】Java锁与监视器

    锁的相关基本概念.了解底层的Object 监视器~ 在Java中,与线程通信相关的几个方法,是定义在Object中的,大家都知道Object是Java中所有类的超类 在Java中,所有的类都是Obje ...

最新文章

  1. android textview参差不齐,android textView 排版显示参差不齐的解决方法
  2. 单例设计模式singleton
  3. html5+开发window桌面图标,js模仿windows桌面图标排列算法具体实现(附图)
  4. python PIL.Image获取图像像素时, 图像的原点及x,y的方向
  5. 第五届河南省大学生程序设计竞赛 题解
  6. 关于TableView中图片的延时加载(转)
  7. 学习 - java位运算符
  8. 【乡音】海安话四级考试
  9. leetcode 121 股票买卖问题系列
  10. 思维导图软件下载与安装 记录xmind安装过程
  11. 文件对应的Content-Type类型
  12. 秒杀各大网盘的不限速大文件传输工具
  13. 泛函分析复习笔记(三)紧算子与Fredholm算子
  14. 抗DoS、DDoS防火墙产品大检阅(转)
  15. RSA用私钥加密数据公钥解密数据(不是签名验证过程)
  16. JAVA线程状态的10种转换
  17. cubemx 配置多通道ADC进行ADC采样
  18. HDOj 4544
  19. java的Pattern类
  20. Windows GDI+ 详解

热门文章

  1. io多路复用的原理和实现_IO多路复用的三种机制:select 、poll 、epoll
  2. 联想昭阳k29轴拆机步骤图_UG8.5编程加工之固定轴曲面轮廓铣削加工方法
  3. android自定义水波纹,android 自定义view-水波纹进度球
  4. 制打印如下所示的n行数字金字塔_一日一技:在Python中实现阿拉伯数字加上中文数字...
  5. 未来十年,Java 仍会是最受欢迎的编程语言吗?
  6. 雷军1994年写的诗一样的代码,我把它运行起来了!
  7. 镗孔指令g76格式_数控车床螺纹切削指令G32,用途广泛,可分度车削多头螺纹
  8. python3编程题_Python3简单面试编程题
  9. ssm上传文件进度条_ssm学习笔记-三种文件上传方式
  10. 电脑故障扫描修复软件_253个电脑故障修复工具