Java 基于时间的线程安全优先级队列
我需要一些类似队列的DataStract来执行以下任务:Java 基于时间的线程安全优先级队列,java,scala,data-structures,scheduling,Java,Scala,Data Structures,Scheduling,我需要一些类似队列的DataStract来执行以下任务: 某些线程添加带有附加延迟值(例如秒)的数据项,例如队列。添加(数据,延迟) 可以有不同的延迟,也可以有相同的延迟,并且队列应该充当优先级队列:延迟越小,项目越接近末尾(出列越快) 排队项目的每秒钟延迟应减少1,直到达到0(然后保持不变为0) 在delay为0的项目中,排队顺序正好是插入顺序(尽管到达0的顺序更好) 一些客户端线程系统地从这个队列中获取元素,它只给出delay=0元素。如果不存在这样的代码,那么它将阻塞或抛出 因此,我想要一
队列。添加(数据,延迟)
延迟
应减少1,直到达到0(然后保持不变为0)delay
为0
的项目中,排队顺序正好是插入顺序(尽管到达0
的顺序更好)delay=0
元素。如果不存在这样的代码,那么它将阻塞或抛出java
或scala
是否有生产就绪的解决方案?我不想再发明一辆自行车
编辑:在java标准库中似乎确实存在这样的东西:
DelayQueue
,在回答以下问题之前先查看一下。您可以使用一个PriorityQueue
作为输入可比较的
对象。
您应该根据时间戳
字段比较这些对象(越小越好);正如@Henry已经提到的,最好存储时间戳
,而不是延迟
。这很容易实现;只需存储currentTime+delay
然后,当客户端请求head元素时,您需要创建一个执行以下操作的synchronized
方法:
- 首先
检查head元素是否有peek()
时间戳
- 如果是,
此元素,否则抛出poll()
第二种解决方案(根据我的评论进行移植):
实际上,可以添加ScheduledThreadPoolExecutor作为中间层; 现在您不需要
时间戳
,只需向执行器提供延迟
当每个runnable/callable
执行时,相应的对象被添加到另一个正常的FIFO队列中,该队列将立即可用于轮询
您的客户端现在可以从此第二个FIFO队列轮询元素。与其每秒修改所有项目的
延迟
,不如在它们准备退出队列时存储时间戳。队列的顺序不会因此而改变,并且可以省去更新工作。@Henry,这确实是合理的。您看过ScheduledThreadPoolExecutor吗?听起来您真的应该使用ScheduledThreadPoolExecutor,因为它将延迟优先级队列和线程池包装在一起。实际上,可以添加ScheduledThreadPoolExecutor作为中间步骤;当到达延迟=0时,它将把它添加到另一个队列中,在那里它将立即可用于轮询;但无论如何,您需要第二个队列(但这次不一定是优先队列)。使用了您最初的建议,这确实是微不足道的。谢谢