并发混合队列和侦听器

时间:2012-12-14 12:20:29

标签: java multithreading queue

我有EventsManager从外部来源接收事件。 Event有一个type和一个value

听众可以在EventsManager注册,以获知某类事件的成功价值。

对于给定类型的事件,EventsManager承诺两件事:

  • 同一个值不会连续两次发送(当听众收到通知时,他们可以保证他们收到的值与上一个通知的值不同。)
  • 对于给定类型的事件,必须保留从外部源接收值的顺序。

我有一个有效的synchronized版本,但我想提高吞吐量。

典型用途:< 1k听众,< 10k事件类型,<每秒收到1M个事件(但大多数事件被丢弃,因为没有为该类事件注册的侦听器或值未更改)。

  • 实现该行为的最有效策略是什么(例如,我可以在每个事件类型中使用一个队列/锁并将它们保存在ConcurrentMap中但是拥有10k队列听起来不是一个好主意)?
  • 是否有任何现有的库可以使用可扩展的并发结构?

示例:监听器lst1想要收听type1类型的事件 EventsManager收到:

event: type2, value: 2
event: type1, value: 1
event: type1, value: 1 //no change => discard
event: type3, value: 4
event: type1, value: 7

lst1应按顺序收到:1(仅一次),然后7

2 个答案:

答案 0 :(得分:1)

此评论会随着评论的添加而改变。

IF 您可以控制外部源,最快的改进是防止该源发送保证被丢弃/忽略的消息。例如,外部源可以保留Map或其他一些允许快速查找和更新的数据结构。外部来源将能够确定需要将哪些信息发送到您的EventQueue

如果控制外部源,那么队列中可能会包含您在原始帖子中声明的通用Event 。我建议您添加从Radix Tree投放的Queue。我的意思是将队列生成的值存储在radix tree中。这允许以下内容:

  

与平衡树不同,基数树允许查找,插入和   在O(k)时间而不是O(log n)中删除。这似乎不是一个   优点,因为通常k≥logn,但在每个平衡树中   比较是一个字符串比较,需要O(k)最坏情况时间,很多   由于长公共前缀(在这种情况下),其实际上很慢   比较从字符串的开头开始)。在一个特里,所有   比较需要恒定的时间,但需要进行m次比较   一串长度为m的。基数树可以执行这些操作   更少的比较,并且需要更少的节点。

更新

问题:

  

您知道基数树的线程安全实现吗?

Concurrent Trees没有测试过这些!

API: ConcurrentRadixTree

答案 1 :(得分:1)

我会尝试实现此事件流

  1. 所有传入的事件都会放入初始 EventQueue
  2. EventDispatcherThread 会为每种类型(简单的队列地图)读取EventQueue和过滤并路由相应的 EventQueue LI>
  3. EventListernerThread 的多个实例正在读取其类型的相应EventQueue ...
  4. 不需要锁定/同步