Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/372.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 并发合并队列和侦听器_Java_Multithreading_Queue - Fatal编程技术网

Java 并发合并队列和侦听器

Java 并发合并队列和侦听器,java,multithreading,queue,Java,Multithreading,Queue,我有一个从外部源接收事件的EventsManager。事件具有类型和值 监听器可以注册到EventsManager,以了解特定类型事件的后续值 对于给定类型的事件,EventsManager承诺了两件事: 同一个值不会在一行中发送两次(当侦听器收到通知时,可以保证它们收到的值与以前的通知不同) 对于给定类型的事件,必须保留从外部源接收值的顺序 我有一个正常工作的同步版,但我想提高吞吐量 典型用途:

我有一个从外部源接收事件的
EventsManager
事件
具有
类型

监听器可以注册到
EventsManager
,以了解特定类型事件的后续值

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

  • 同一个值不会在一行中发送两次(当侦听器收到通知时,可以保证它们收到的值与以前的通知不同)
  • 对于给定类型的事件,必须保留从外部源接收值的顺序
我有一个正常工作的
同步版
,但我想提高吞吐量

典型用途:<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

此答案将随着注释的添加而更改

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

如果您不控制外部源,则队列可能会像您在原始帖子中所说的那样保存一个通用的
事件。我建议添加一个
基树
,它是从
队列
馈送的。我的意思是将队列生成的值存储在。这考虑到以下几点:

与平衡树不同,基数树允许查找、插入和删除 在O(k)时间而不是O(logn)时间内删除。这看起来不像是一场比赛 优势,因为通常k≥ 日志n,但在平衡树中,每个 比较是一种字符串比较,需要O(k)最坏情况时间,很多 由于公共前缀较长(在本例中为 比较从字符串的开头开始)。在一个trie中,所有 比较需要固定的时间,但需要m个比较才能查看 沿着长度为m的一串。基数树可以使用 比较更少,需要的节点也更少

更新

问题:

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

没有测试过这些


我将尝试实现此事件流

  • 所有传入事件都放入初始事件队列
  • EventDispatcherThread读取事件队列,并过滤事件并将其路由到每种类型的相应EventQueue(简单的队列映射)
  • EventListernThread的多个实例正在读取其类型的相应事件队列

  • 不需要锁定/同步

    事件类型是否具有任何逻辑分组/通用性?忘记添加,当前吞吐量是多少,预期是多少?您可以假设不同的事件类型是独立的。假设一种是车速,另一种是室外温度。使用同步版本,当前吞吐量约为每秒200k个事件。不确定是否有用,但最近有一份JavaExperts新闻稿报道了可能感兴趣的事件。@OldCurmudgeon看起来很有希望。不幸的是,我无法控制外部源。因此,我需要在我这边进行过滤。@Assylas我已经提供了一个指向基数树并发实现的链接,我还没有测试过,所以请注意:)这似乎会以最糟糕的方式扩展。@Woot4Moo另一方面,它节省了大量的上下文切换。@Assylas我可以肯定地看到,然而,我确实看到的问题是,步骤3中描述的
    EventListenerThread
    可能会导致执行重复的工作,因为这并不排除必须使用同步。或者至少是一个负载平衡的概念。@Woot4Moo当然,如果不排除任何东西,因为这取决于您的决定。我认为“无需同步”就足够了同时,众所周知,同步是性能杀手。我希望我不需要提及线程池。。。