Java 在一个时间段内具有时间戳元素的队列

Java 在一个时间段内具有时间戳元素的队列,java,data-structures,queue,Java,Data Structures,Queue,我想存储在队列中,数据结构无关紧要,只有我在当前时间最后5分钟内插入的元素。任何旧的东西都应该被删除,这样每当我得到队列的大小时,它就会给出过去5分钟内插入的对象的数量 基本上,我所要知道的就是在下一次调用之前,我的应用程序在过去5分钟内对服务器进行了多少次http调用 如果有人知道可能有此实现的现有库,请共享。使用哪种语言?队列是持久的还是在内存中 如果您在Java中需要这种行为,您可以使用,并让一个单独的线程在一个紧密的循环中连续调用queue.take(),以排出过期的项目queue.si

我想存储在队列中,数据结构无关紧要,只有我在当前时间最后5分钟内插入的元素。任何旧的东西都应该被删除,这样每当我得到队列的大小时,它就会给出过去5分钟内插入的对象的数量

基本上,我所要知道的就是在下一次调用之前,我的应用程序在过去5分钟内对服务器进行了多少次http调用


如果有人知道可能有此实现的现有库,请共享。

使用哪种语言?队列是持久的还是在内存中


如果您在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个队列