Java 在一个时间段内具有时间戳元素的队列
我想存储在队列中,数据结构无关紧要,只有我在当前时间最后5分钟内插入的元素。任何旧的东西都应该被删除,这样每当我得到队列的大小时,它就会给出过去5分钟内插入的对象的数量 基本上,我所要知道的就是在下一次调用之前,我的应用程序在过去5分钟内对服务器进行了多少次http调用Java 在一个时间段内具有时间戳元素的队列,java,data-structures,queue,Java,Data Structures,Queue,我想存储在队列中,数据结构无关紧要,只有我在当前时间最后5分钟内插入的元素。任何旧的东西都应该被删除,这样每当我得到队列的大小时,它就会给出过去5分钟内插入的对象的数量 基本上,我所要知道的就是在下一次调用之前,我的应用程序在过去5分钟内对服务器进行了多少次http调用 如果有人知道可能有此实现的现有库,请共享。使用哪种语言?队列是持久的还是在内存中 如果您在Java中需要这种行为,您可以使用,并让一个单独的线程在一个紧密的循环中连续调用queue.take(),以排出过期的项目queue.si
如果有人知道可能有此实现的现有库,请共享。使用哪种语言?队列是持久的还是在内存中
如果您在Java中需要这种行为,您可以使用,并让一个单独的线程在一个紧密的循环中连续调用
queue.take()
,以排出过期的项目queue.size()
随后将为您提供队列中剩余未过期项目的大小。这要求您放入DelayedQueue的项实现接口,并将值5分钟返回给.getDelay()
方法。您可以使用带有时间戳的优先级队列作为密钥。因此,当调用Peek()时,始终会得到队列中最早的时间戳。然后每次转到“查询窗口大小”中的项目数:清除窗口外的项目,并返回仍在优先级队列中的项目数
例如:
public class CountInWindow {
/**
* Adding a main just for testing
* @param args
* @throws InterruptedException
*/
public static void main(String[] args) throws InterruptedException {
System.out.println("test started");
CountInWindow test = new CountInWindow(5000); //5 seconds for testing
test.debug = true;
test.insertTimeStamp(System.currentTimeMillis());
Thread.sleep(100);//sleep
test.insertTimeStamp(System.currentTimeMillis());
Thread.sleep(100);//sleep
test.insertTimeStamp(System.currentTimeMillis());
Thread.sleep(100);//sleep
test.insertTimeStamp(System.currentTimeMillis());
Thread.sleep(5040);//sleep 5 secs
test.insertTimeStamp(System.currentTimeMillis());
Thread.sleep(100);//sleep
test.insertTimeStamp(System.currentTimeMillis());
System.out.println(test.getWindowCount()); //Should be 2 not 6.
System.out.println("test done");
}
java.util.PriorityQueue<Long> window;
public static final long FIVE_MINS_IN_MS = 300000l;
public final long WINDOW_SIZE;
public boolean debug = false;
//Constructor which defaults to 5mins
public CountInWindow(){
WINDOW_SIZE = FIVE_MINS_IN_MS;
window = new java.util.PriorityQueue<Long>();
}
//Constructor for any size window
public CountInWindow(long windowSize){
WINDOW_SIZE = windowSize;
window = new java.util.PriorityQueue<Long>();
}
/**
* Add a new timestamp to the window's queue
* @param ts
*/
public void insertTimeStamp(long ts){
window.add(ts);
}
/**
* Clean up items outside the window size and then return the count of times still in the window.
* @return A count of timestamps still inside the 5 mins window.
*/
public int getWindowCount(){
long currTime = System.currentTimeMillis();
//Clean out old Timestamps
while((currTime - window.peek().longValue()) > WINDOW_SIZE){
long drop = window.remove().longValue();
if(debug)System.out.println("dropping item:" + drop);
}
return window.size();
}
}
公共类计数窗口{
/**
*添加一个仅用于测试的main
*@param args
*@抛出中断异常
*/
公共静态void main(字符串[]args)引发InterruptedException{
System.out.println(“测试已启动”);
CountInWindow测试=新的CountInWindow(5000);//测试时间为5秒
test.debug=true;
test.insertTimeStamp(System.currentTimeMillis());
Thread.sleep(100);//sleep
test.insertTimeStamp(System.currentTimeMillis());
Thread.sleep(100);//sleep
test.insertTimeStamp(System.currentTimeMillis());
Thread.sleep(100);//sleep
test.insertTimeStamp(System.currentTimeMillis());
Thread.sleep(5040);//睡眠5秒
test.insertTimeStamp(System.currentTimeMillis());
Thread.sleep(100);//sleep
test.insertTimeStamp(System.currentTimeMillis());
System.out.println(test.getWindowCount());//应该是2而不是6。
System.out.println(“测试完成”);
}
java.util.PriorityQueue窗口;
公共静态最终长五分钟(单位:米)=300000升;
公共最终长窗口大小;
公共布尔调试=false;
//构造函数,默认为5分钟
公共计数窗口(){
窗口大小=五分钟(单位:毫秒);
window=new java.util.PriorityQueue();
}
//任何大小窗口的构造函数
公共计数窗口(长窗口大小){
窗口大小=窗口大小;
window=new java.util.PriorityQueue();
}
/**
*向窗口队列添加新的时间戳
*@param ts
*/
公共void insertTimeStamp(长ts){
窗口。添加(ts);
}
/**
*清理窗口大小之外的项目,然后返回仍在窗口中的次数。
*@返回仍在5分钟窗口内的时间戳计数。
*/
public int getWindowCount(){
long currTime=System.currentTimeMillis();
//清除旧的时间戳
而((currTime-window.peek().longValue())>窗口大小){
long drop=window.remove().longValue();
if(debug)System.out.println(“删除项:“+drop”);
}
返回窗口。size();
}
}
我已经实现了一个类似的FadingLinkedList
public class FadingLinkedList<E> {
private transient Entry<E> header = new Entry<E>(null, null);
/**
* ms
*/
private long livingTime;
/**
* Constructs FadingLinkedList with elements of living time livingTime in
* milliseconds
*/
public FadingLinkedList(long livingTime) {
this.livingTime = livingTime;
}
/**
* remove all faded elements,
*
* @return the count of not faded
*/
public synchronized int removeFaded() {
long now = System.nanoTime();
int count = 0;
Entry<E> prev = header;// the last living Entry in the loop
for (Entry<E> e = header.next; e != null; e = e.next) {
if (TimeUnit.NANOSECONDS.toMillis(now - e.birthTime) >= livingTime) {
// cut off this list here.
prev.next = null;
break;
}
count++;
prev = e;
}
return count;
}
/**
* Returns the number of elements that not faded.
*/
public int size() {
return removeFaded();
}
public synchronized void push(E e) {
Entry<E> newEntry = new Entry<E>(e, header.next);
header.next = newEntry;
}
private static class Entry<E> {
E element;
Entry<E> next;
long birthTime;
Entry(E element, Entry<E> next) {
this.element = element;
this.next = next;
this.birthTime = System.nanoTime();
}
}
public synchronized void clear() {
header.next = null;
}
public synchronized int getAndClear() {
int size = size();
clear();
return size;
}
公共类FadingLinkedList{
私有临时条目头=新条目(null,null);
/**
*ms
*/
私人生活时间长;
/**
*用生活时间元素构建FadingLinkedList
*毫秒
*/
公共淡入淡出链接列表(长时间){
this.livingTime=livingTime;
}
/**
*移除所有褪色的元素,
*
*@返回未褪色的计数
*/
公共同步的int-removeded(){
long now=System.nanoTime();
整数计数=0;
Entry prev=header;//循环中最后一个有效的条目
for(条目e=header.next;e!=null;e=e.next){
if(时间单位纳秒托米利(现在-e.生日)>=livingTime){
//把这张单子删掉。
prev.next=null;
打破
}
计数++;
prev=e;
}
返回计数;
}
/**
*返回未褪色的元素数。
*/
公共整数大小(){
return-remove();
}
公共同步无效推送(E){
Entry newEntry=新条目(e,header.next);
header.next=newEntry;
}
私有静态类条目{
E元素;
进入下一步;
出生时间长;
条目(E元素,条目下一个){
this.element=元素;
this.next=next;
this.birthdime=System.nanoTime();
}
}
公共同步无效清除(){
header.next=null;
}
public synchronized int getAndClear(){
int size=size();
清除();
返回大小;
}
}您忘了提到诸如:所需的平台/语言等内容。谢谢,但是这种方法的唯一问题是线程必须非常频繁地运行,以使调用的结果最好
queue.size()
。是的-它需要是一个紧密循环(例如while queue.take()!=null)。请注意,queue.take()将一直阻塞,直到队列中要获取的元素过期为止。然后,迭代的频率取决于项目放置在队列上的频率(以及它们过期的频率),而不是基于时间的垃圾收集(因此queue.size()在任何时候都是精确的)。谢谢,我没有意识到这个队列。take()将一直阻止,直到队列中要获取的元素过期。了解他们是如何实现DelayQueue的将是一件有趣的事情——他们可能在内部使用2个队列