Java并发ReadWriteLock与我自己的时间戳

Java并发ReadWriteLock与我自己的时间戳,java,concurrency,readwritelock,Java,Concurrency,Readwritelock,ReentrantReadWriteLock非常适合在接收时以编程方式基于时间戳的读写场景 PUT(KEY=1,VALUE=1) PUT(KEY=1,VALUE=2) GET(KEY=1) PUT(KEY=1,VALUE=1) ... JavaReentrantReadWriteLock将根据Java自身提供的时间戳自动按顺序同步所有这些文件。 但是,我需要如何使用随每个请求一起提供的外部时间戳 PUT(KEY=1,VALUE=1,TIMESTAMP=13000000000000) PUT(K

ReentrantReadWriteLock
非常适合在接收时以编程方式基于时间戳的读写场景

PUT(KEY=1,VALUE=1)
PUT(KEY=1,VALUE=2)
GET(KEY=1)
PUT(KEY=1,VALUE=1)
...
Java
ReentrantReadWriteLock
将根据Java自身提供的时间戳自动按顺序同步所有这些文件。 但是,我需要如何使用随每个请求一起提供的外部时间戳

PUT(KEY=1,VALUE=1,TIMESTAMP=13000000000000)
PUT(KEY=1,VALUE=2,TIMESTAMP=13500000000000)
GET(KEY=1,TIMESTAMP=14000000000000)
PUT(KEY=1,VALUE=1,TIMESTAMP=15000000000000)
...

如何设计按外部时间戳排序的读写锁

简短回答:

同步接收时间戳数据的通道,或在接收端使用有序的并发数据结构,如
ConcurrentSkipListMap
。同时,询问您是否需要维持此订单

p.S.
ReentrantReadWriteLock
不使用类似于时间戳的实体来建立排序,其公平调度算法不包括可重用的条目重新排序
ReentrantReadWriteLock
通过使用基于CLH的锁队列

长答案:

虽然您想要做的事情很可能是无法避免的,但质疑您是否真的需要并发和/或分布式系统中的各种精度和一致性总是好的

你为什么关心这个问题

听起来您希望通过使用系统中另一层的数据排序来保持公平性。您是否需要将这两个层分开,可能是因为其中一个超出了您的控制范围,或者是因为它们需要保持语义上的分离?如果是这样,你可以在这里再问自己几个问题

是否绝对有必要为每个请求维护此订单

这是您业务逻辑的关键部分吗? 它实际上是由您关心的上层组件建立的吗

  • 如果它基于某些请求通过您无法控制的网络(如Internet)到达的时间,那么很可能您并不真正关心这种排序,放松一致性要求可能会带来更高的吞吐量。在一个高度并发、不公平的环境中,不公平地替换请求的速度要比在一个利用其资源有问题的公平环境中的请求更快,这并不少见
  • 如果它基于一个超级快速的时间戳颁发者,该颁发者在所有请求上建立一个总订单,则您可以修改您的系统,以便时间戳颁发者成为通过中断器或ArrayBlockingQueue向系统第二层提供请求的单一生产者
  • 你真的会收到不正常的请求吗

    你可能正在解决一个你永远不会真正面对的问题,或者你将在遥远的未来面临的问题,同时你的时间可以更好地花在其他地方

    如果情况并非如此,并且您实际希望接收无序(以外部时间戳顺序)请求,那么层之间的通信通道就是在系统中引入“无序”的组件之一。这可能是因为有人故意想用一致性来换取吞吐量,也可能是因为在没有额外工作的情况下,该通道无法满足系统的需要

    考虑是否更容易在其中强制实现严格的一致性,或者更容易保持原样并在收到请求后对其进行排序

    • 我们已经用SingleProducertItems的方法讨论了前者™ - 如果你没有对频道的控制权,这也可能是不可行的
    • 对于后者,您可以尝试使用有序并发数据结构。 将时间戳映射到请求可能是一个好的解决方案。如果你不害怕尝试应用论文中的想法,你可能想看看

    从请求中复制它们!如何将请求中的时间戳放入这些锁中?您可以对此进行扩展吗?我需要使用随每个请求一起提供的外部时间戳。您的请求看起来如何?put?key=key&value=value×tamp=TIME get?key=key×tamp=TIME您应该能够准确地提取出与提取出的密钥相同的时间。你面临的问题是什么?