资讯专栏INFORMATION COLUMN

Deque的使用实例

jsummer / 2751人阅读

摘要:序双向队列是的一个子接口,双向队列是指该队列两端的元素既能入队也能出队。使用场景比如工作窃取,比如限流。限流实例使用来限流,其中为事件窗口,为该事件窗口的最大值。

双向队列(Deque),是Queue的一个子接口,双向队列是指该队列两端的元素既能入队(offer)也能出队(poll)。使用场景比如工作窃取,比如限流。

限流实例

使用deque来限流,其中timeIntervalInMs为事件窗口,maxLimit为该事件窗口的最大值。

public class MyRateLimiter {

    private static final Logger LOGGER = LoggerFactory.getLogger(DemoRateLimiter.class);

    private final Deque queue;

    private long timeIntervalInMs;

    public MyRateLimiter(long timeIntervalInMs, int maxLimit) {
        this.timeIntervalInMs = timeIntervalInMs;
        this.queue = new LinkedBlockingDeque(maxLimit);
    }

    public boolean incrAndReachLimit(){
        long currentTimeMillis = System.currentTimeMillis();
        boolean success = queue.offerFirst(currentTimeMillis);
        if(success){
            //没有超过maxLimit
            return false;
        }

        synchronized (this){
            //queue is full
            long last = queue.getLast();

            //还在时间窗口内,超过maxLimit
            if (currentTimeMillis - last < timeIntervalInMs) {
                return true;
            }
            LOGGER.info("time window expired,current:{},last:{}",currentTimeMillis,last);
            //超过时间窗口了,超过maxLimit的情况下,重置时间窗口
            queue.removeLast();
            queue.addFirst(currentTimeMillis);

            return false;
        }

    }
}

测试

@Test
    public void testDeque() throws InterruptedException {
        DemoRateLimiter limiter = new DemoRateLimiter(5*1000,3);
        Callable test = new Callable(){

            @Override
            public Void call() throws Exception {
                for(int i=0;i<1000;i++){
                    LOGGER.info("result:{}",limiter.incrAndReachLimit());
                    try {
                        Thread.sleep(500);
                    } catch (InterruptedException e) {
                        e.printStackTrace();
                    }
                }
                return null;
            }
        };
        ExecutorService pool = Executors.newFixedThreadPool(10);
        pool.invokeAll(Arrays.asList(test,test,test,test,test));

        Thread.sleep(100000);
    }
小结

这里使用了Deque的容量来作为时间窗口的限流大小,利用两端来判断时间窗口,相对来讲有点巧妙。

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/70393.html

相关文章

  • Java™ 教程(Deque接口)

    Deque接口 通常读作deck,deque是双端队列,双端队列是元素的线性集合,支持在两个端点处插入和移除元素,Deque接口是比Stack和Queue更丰富的抽象数据类型,因为它同时实现堆栈和队列。Deque接口定义了访问Deque实例两端元素的方法,提供了插入、移除和检查元素的方法,ArrayDeque和LinkedList等预定义类实现了Deque接口。 请注意,Deque接口既可以用作后...

    lastSeries 评论0 收藏0
  • Python 进阶之路 (七) 隐藏神奇宝藏:探秘Collections

    摘要:它需要一个函数默认工厂作为其参数。默认情况下设置为,即如果键不存在则为,并返回并显示默认值。因此,它是一个无序集合,其中元素及其各自的计数存储为字典。这相当于其他语言的或。使用,我们不必使用整数索引来访问元组的成员。 神奇的collections 大家好,今天想和大家分享一个Python里面非常棒的模快:Collections 该模块实现了专门的容器数据类型,为Python的通用内置容...

    rickchen 评论0 收藏0
  • java集合-List

    摘要:会死循环,因为栈内不会弹出所以判断会一直执行。集合用于模拟队列这种数据结构,队列通常是指先进先出的容器。集合不仅提供了的功能,还提供了双端队列,栈的功能。如果有多个线程需要访问集合中的元素,需要考虑使用将几个包装成线程安全集合。 List判断两个对象相等只通过equals方法比较返回true即可。 public class A { @Override public ...

    MasonEast 评论0 收藏0
  • 重读《学习JavaScript数据结构与算法-第三版》- 第5章 队列

    摘要:定场诗马瘦毛长蹄子肥,儿子偷爹不算贼,瞎大爷娶个瞎大奶奶,老两口过了多半辈,谁也没看见谁前言本章为重读学习数据结构与算法第三版的系列文章,主要讲述队列数据结构双端队列数据结构以及队列相关应用。 定场诗 马瘦毛长蹄子肥,儿子偷爹不算贼,瞎大爷娶个瞎大奶奶,老两口过了多半辈,谁也没看见谁! 前言 本章为重读《学习JavaScript数据结构与算法-第三版》的系列文章,主要讲述队列数据结构、...

    charles_paul 评论0 收藏0

发表评论

0条评论

jsummer

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<