Java 基于时间的线程安全优先级队列

Java 基于时间的线程安全优先级队列,java,scala,data-structures,scheduling,Java,Scala,Data Structures,Scheduling,我需要一些类似队列的DataStract来执行以下任务: 某些线程添加带有附加延迟值(例如秒)的数据项,例如队列。添加(数据,延迟) 可以有不同的延迟,也可以有相同的延迟,并且队列应该充当优先级队列:延迟越小,项目越接近末尾(出列越快) 排队项目的每秒钟延迟应减少1,直到达到0(然后保持不变为0) 在delay为0的项目中,排队顺序正好是插入顺序(尽管到达0的顺序更好) 一些客户端线程系统地从这个队列中获取元素,它只给出delay=0元素。如果不存在这样的代码,那么它将阻塞或抛出 因此,我想要一

我需要一些类似队列的DataStract来执行以下任务:

  • 某些线程添加带有附加延迟值(例如秒)的数据项,例如
    队列。添加(数据,延迟)
  • 可以有不同的延迟,也可以有相同的延迟,并且队列应该充当优先级队列:延迟越小,项目越接近末尾(出列越快)
  • 排队项目的每秒钟
    延迟
    应减少1,直到达到0(然后保持不变为0)
  • delay
    0
    的项目中,排队顺序正好是插入顺序(尽管到达
    0
    的顺序更好)
  • 一些客户端线程系统地从这个队列中获取元素,它只给出
    delay=0
    元素。如果不存在这样的代码,那么它将阻塞或抛出
  • 因此,我想要一些队列+一点调度的功能,线程安全。我怀疑,在某些情况下,这类事情应该是一项相当常规的任务

    我的问题:对于这类任务,
    java
    scala
    是否有生产就绪的解决方案?我不想再发明一辆自行车


    编辑:在java标准库中似乎确实存在这样的东西:
    DelayQueue
    ,在回答以下问题之前先查看一下。

    您可以使用一个
    PriorityQueue
    作为输入
    可比较的
    对象。 您应该根据
    时间戳
    字段比较这些对象(越小越好);正如@Henry已经提到的,最好存储
    时间戳
    ,而不是
    延迟
    。这很容易实现;只需存储
    currentTime+delay

    然后,当客户端请求head元素时,您需要创建一个执行以下操作的
    synchronized
    方法:

    • 首先
      peek()
      检查head元素是否有
      时间戳
    • 如果是,
      poll()
      此元素,否则抛出

    第二种解决方案(根据我的评论进行移植):


    实际上,可以添加ScheduledThreadPoolExecutor作为中间层; 现在您不需要
    时间戳
    ,只需向执行器提供
    延迟

    当每个
    runnable/callable
    执行时,相应的对象被添加到另一个正常的FIFO队列中,该队列将立即可用于轮询


    您的客户端现在可以从此第二个FIFO队列轮询元素。

    与其每秒修改所有项目的
    延迟
    ,不如在它们准备退出队列时存储时间戳。队列的顺序不会因此而改变,并且可以省去更新工作。@Henry,这确实是合理的。您看过ScheduledThreadPoolExecutor吗?听起来您真的应该使用ScheduledThreadPoolExecutor,因为它将延迟优先级队列和线程池包装在一起。实际上,可以添加ScheduledThreadPoolExecutor作为中间步骤;当到达延迟=0时,它将把它添加到另一个队列中,在那里它将立即可用于轮询;但无论如何,您需要第二个队列(但这次不一定是优先队列)。使用了您最初的建议,这确实是微不足道的。谢谢