【发布时间】:2011-11-29 15:19:28
【问题描述】:
我通过在不同线程上运行的交互式会话 + 私有源 (InputStream) 连接到外部服务。在交互式会话中,我发送传出消息并接收包含不同字段的对象的同步响应,其中一个是 ID 和确认成功或失败的“状态”。同时,我在此 ID 的私人订阅源上收到消息,并带有进一步的“状态”更新。我目前将有关每个 ID 的状态信息存储在 ConcurrentHashMap 中。我必须在这些对象上保持正确的事件序列,但我目前遇到了竞争条件,有时我会在接收和处理交互式会话上的同步响应之前处理和更新私人提要上的对象,因此让我ID 的状态已过时且不正确。
理想情况下,我希望有某种类型的带有 PutIfKeyExistOrWait (w timeout) 方法的集合,它只会在密钥存在或等待时更新值,我可以在处理私有提要上的对象时使用它。
有谁知道是否有合适的集合可用,或者可以建议我的问题的替代解决方案吗?谢谢。
【问题讨论】:
-
PutIfKeyExistOrWait 如果稍后(当 ID 已经存在)您收到 2 个异步通知,但由于竞争条件而以错误的顺序处理它们,则将无济于事。听起来唯一的防弹方法是传入消息是否具有序列号。如果他们不这样做,我想下一个最好的办法是在您收到每条消息时附加时间戳,然后根据时间戳对状态进行排序。
-
@EliAcherkan 谢谢。私人订阅源上的异步消息是在单个线程中接收的,因此我可以“保证”这些消息的正确顺序。只有同步响应与异步消息会导致问题。时间戳也不起作用。消息通常在同一毫秒内收到,并且无法保证在私人提要上的消息之前收到同步响应,因此存在问题。
-
对不起,我能想到的唯一选择是让交互式会话有一个
synchronized块,用于检查密钥是否已由私人提要插入到地图中,并插入/更新相应的状态。 -
你的问题我还是不清楚。您向该服务发送一条消息,然后您会从该服务获得响应并从提要中获得“更新”。 ID 是否像消息号一样唯一? (这意味着您从服务中获得一条消息,并从具有此 ID 的提要中获得一条消息。)您正在等待处理,直到您从服务和提要中获得一对相关消息?您能否从给定 ID 的提要中获取额外消息?
-
@toto2 ID 就像一个订单 ID,我需要始终保持订单的准确状态。我在交互式会话中获得了一个同步响应,并且(通常)在私人提要上获得了 ID 的多个状态更新。竞争条件发生在初始交互式响应与同时接收的私有源更新之间。私人提要上的任何后续更新(几秒钟或几分钟后)都不是问题。
标签: java collections concurrency