Java Concurrency ReadWriteLock和我自己的时间戳

时间:2016-03-17 05:56:57

标签: java concurrency readwritelock

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)
...

如何设计外部时间戳排序的ReadWriteLock?

1 个答案:

答案 0 :(得分:0)

简答:

同步通过其接收带时间戳数据的通道,或使用接收端上的ConcurrentSkipListMap等有序并发数据结构。同时质疑你是否需要保持这种排序。

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

答案很长:

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

你为什么关心这个问题?

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

是否必须为每个请求维护此订单?

这种排序是您业务逻辑的重要组成部分吗? 它实际上是由你关心的上层组件建立的吗?

  1. 如果它是基于某些请求通过您控制之外的网络(如Internet)到达的时间,则可能您并不真正关心此顺序,并且放宽您的一致性要求可能会导致更高吞吐量。在高度并发,不公平的环境中,不公平的流离失所的请求比在利用其资源方面存在问题的公平环境中的请求更快地提供服务的情况并不罕见。
  2. 如果它基于单个超快速时间戳发布者,可以对所有请求建立总订单,您可以修改系统,以便时间戳发布者成为提供请求的单个生产者系统的第二层通过Disruptor或ArrayBlockingQueue。
  3. 您是否真的收到了无序请求?

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

    如果情况并非如此,并且您实际上希望收到无序(在您的外部时间戳顺序中)请求,那么您的层之间的通信通道是在您的系统中引入“无序”的组件之一。这可能是因为有人故意想要交换吞吐量的一致性,或者可能是因为没有额外的工作,该渠道不适合您的系统需求。

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