情况如下:
我处理通过套接字Connection
收到的数据包,并且每个数据包都有一个不同的ID和一般类Message
的关联子类(所以FooMessage
,{{1 },BarMessage
)。
我需要使用这些消息来更新程序中的一些信息(信息存储在不同的类中,例如HelloMessage
涉及与AInformation
有关的所有内容,A
相关的事情到BInformation
种类的东西,B
等等......)。
为此,我引入了第三方:CInformation
,它监听某些特定类型的消息,并使用它们来更新与Listener
相关联的Information类。我们有Listener
来处理AListener
和FooMessage
,有一些特定的函数可以更新BarMessage
,AInformation
来处理BListener
和{{1}并更新BarMessage
...
以下是通过套接字连接发出的HelloMessage
的生命周期:
BInformation
由Message
(字节数组)DuhMessage
创建
Connection
被Packet
发送给所有听众(我将解释我执行此步骤的问题,这对我来说是个问题)DuhMessage
,如果有兴趣更新监听器正在处理的信息类型,则消息由函数处理为了处理步骤 2 ,我基本上在Connection
中有一个DuhMessage
列表(此列表必须是线程安全的,因为{{1}可以随时添加到Listener
列表中。 Connection
锁定列表并将Listener
推送到所有Connection
消息队列。 (Connection
有一个消息队列,它一个接一个地消耗它们,更新DuhMessage
类)
这是我用Dia制作的模式,总结了它:
我的问题是:
当我将Listener
推送到Listener
的队列时,我应该复制该对象吗?由于我的Information
可能会尝试同时阅读DuhMessage
的属性,他们不能吗?
这是我为这种情况做的线程安全的deque实现(如果你可以验证它)。
Listener
答案 0 :(得分:1)
答案 1 :(得分:0)
最好的是破坏者模式(并行化管道)的变体。邮件的单个副本将提交给由固定大小的线程池支持的管道。
readonly侦听器的管道片段可以并行处理消息,如果需要,可以为自己使用创建可变副本(比如异步写入数据库)。
管道片段:readonly-> mutating,mutating-> mutating,mutating-> readonly必须进行序列化处理。
一旦所有侦听器/处理程序完成后,调度程序都应销毁原始消息。
复制事件处理程序的一部分将污染其逻辑并损害整个解决方案的可伸缩性。