首页 > 其他分享 >BlockingQueue---DelayQueue

BlockingQueue---DelayQueue

时间:2024-09-20 10:14:01浏览次数:1  
标签:queue return lock 元素 DelayedElement --- DelayQueue public BlockingQueue

总结

  一个无界阻塞队列;

  FIFO

  只包含实现了 Delayed 接口的元素,每个元素都有一个延迟时间,在该延迟时间结束之前,该元素不会从队列中可用。一旦元素的延迟到期,它就可以被取出了,并且取出的顺序是按照延迟到期的时间先后进行的。

  通常用于实现定时任务调度、缓存过期等场景。例如,可以用来管理超时连接或自动删除过期的数据。

特性

  • 无界:可以容纳任意数量的元素。
  • 基于延迟:元素只有在其延迟时间到期后才可被取出。
  • 线程安全:支持多线程同时进行插入和移除操作。
  • 阻塞取元素的操作(如 take())如果在没有延迟到期的元素时会被阻塞,直到有元素的延迟到期。

构造函数

  DelayQueue(): 创建一个新的 DelayQueue 实例。

方法

  • 插入操作:

    • put(E e): 将指定的延迟元素插入此队列。由于 DelayQueue 只接受实现了 Delayed 接口的对象,所以这里的 E 必须是 Delayed 类型。
    • offer(E e): 尝试将指定的延迟元素插入此队列。与 put 方法类似,但不会抛出异常。
  • 移除操作:

    • take(): 检索并移除此队列的头(其延迟已过的元素),如果队列为空,则等待有元素可用。
    • poll(): 检索并移除此队列的头(其延迟已过的元素),如果队列为空,则立即返回 null
    • poll(long timeout, TimeUnit unit): 检索并移除此队列的头(其延迟已过的元素),如果队列为空,则最多等待指定的时间,如果超时队列仍然为空则返回 null
  • 检查操作:

    • peek(): 检索但不移除此队列的头(其延迟已过的元素);如果队列为空,则返回 null
public class DelayQueue<E extends Delayed> extends AbstractQueue<E> implements BlockingQueue<E> {
        private final transient ReentrantLock lock = new ReentrantLock();
        private final PriorityQueue<E> q = new PriorityQueue<E>();

        public DelayQueue() {}

        public boolean offer(E e) {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                q.offer(e);
                if (q.peek() == e) {
                    leader = null;
                    available.signal();
                }
                return true;
            } finally {
                lock.unlock();
            }
        }

        public E poll() {
            final ReentrantLock lock = this.lock;
            lock.lock();
            try {
                E first = q.peek();
                if (first == null || first.getDelay(NANOSECONDS) > 0)
                    return null;
                else
                    return q.poll();
            } finally {
                lock.unlock();
            }
        }
    }

    public class PriorityQueue<E> extends AbstractQueue<E> implements java.io.Serializable {
        private static final int DEFAULT_INITIAL_CAPACITY = 11;
        transient Object[] queue;
        private int size = 0;
        private final Comparator<? super E> comparator;

        public PriorityQueue() {
            this(DEFAULT_INITIAL_CAPACITY, null);
        }

        public PriorityQueue(int initialCapacity, Comparator<? super E> comparator) {
            // Note: This restriction of at least one is not actually needed,
            // but continues for 1.5 compatibility
            if (initialCapacity < 1)
                throw new IllegalArgumentException();
            this.queue = new Object[initialCapacity];
            this.comparator = comparator;
        }

        public boolean offer(E e) {
            if (e == null)
                throw new NullPointerException();
            modCount++;
            int i = size;
            if (i >= queue.length)
                grow(i + 1);
            size = i + 1;
            if (i == 0)
                queue[0] = e;
            else
                siftUp(i, e);
            return true;
        }

        public E poll() {
            if (size == 0)
                return null;
            int s = --size;
            modCount++;
            E result = (E) queue[0];
            E x = (E) queue[s];
            queue[s] = null;
            if (s != 0)
                siftDown(0, x);
            return result;
        }
    }

  

示例

static class DelayedElement implements Delayed {
        private final long delayTime; // 延迟时间
        private final long expire; // 到期时间
        private final String name; // 元素名称

        public DelayedElement(long delay, String name) {
            this.delayTime = delay;
            this.name = name;
            this.expire = System.nanoTime() + TimeUnit.NANOSECONDS.convert(delay, TimeUnit.MILLISECONDS);
        }

        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(expire - System.nanoTime(), TimeUnit.NANOSECONDS);
        }

        @Override
        public int compareTo(Delayed other) {
            if (this == other) {
                return 0;
            }
            if (other instanceof DelayedElement) {
                DelayedElement otherDE = (DelayedElement) other;
                return Long.compare(this.expire, otherDE.expire);
            }
            long diff = getDelay(TimeUnit.NANOSECONDS) - other.getDelay(TimeUnit.NANOSECONDS);
            return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
        }

        @Override
        public String toString() {
            return "DelayedElement{" +
                    "name='" + name + '\'' +
                    ", delay=" + delayTime + "ms" +
                    '}';
        }
    }

    public static void main(String[] args) throws InterruptedException {
        DelayQueue<DelayedElement> queue = new DelayQueue<>();

        // 添加一些延迟元素
        queue.put(new DelayedElement(1000, "One"));
        queue.put(new DelayedElement(500, "Two"));
        queue.put(new DelayedElement(2000, "Three"));

        // 消费者线程
        Thread consumer = new Thread(() -> {
            try {
                while (true) {
                    DelayedElement element = queue.take();
                    System.out.println("Consumed: " + element);
                }
            } catch (InterruptedException e) {
                Thread.currentThread().interrupt();
            }
        });

        consumer.start();

        // 等待一段时间以观察输出
        Thread.sleep(3000);
        consumer.interrupt(); // 停止消费者

        // 结果:
        // Consumed: DelayedElement{name='Two', delay=500ms}
        //Consumed: DelayedElement{name='One', delay=1000ms}
        //Consumed: DelayedElement{name='Three', delay=2000ms}
    }

  

  

标签:queue,return,lock,元素,DelayedElement,---,DelayQueue,public,BlockingQueue
From: https://www.cnblogs.com/anpeiyong/p/18421936

相关文章

  • DevExpress WinForms中文教程:Data Grid - 如何设置视图和列外观?
    本教程将带您了解用于更改网格元素外观的外观设置,在哪里可以找到视图或单个列的这些设置,以及如何更改视图的绘制样式,以便您可以自定义主题绘制的元素。P.S:DevExpressWinForms拥有180+组件和UI库,能为WindowsForms平台创建具有影响力的业务解决方案。DevExpressWinForms能完美构......
  • NetCore Channel-生产者&消费者
    usingSystem.Threading.Channels;namespaceChannelDemo{publicclassChannelMgr{//优势//允许开发者根据需要创建具有固定容量(有界)或无限容量(无界)的通道//staticChannel<string>channel=Channel.CreateBounded<strin......
  • 基于微信小程序的传染病防控宣传系统的设计与实现-计算机毕业设计源码+LW文档
    摘 要由于APP软件在开发以及运营上面所需成本较高,而用户手机需要安装各种APP软件,因此占用用户过多的手机存储空间,导致用户手机运行缓慢,体验度比较差,进而导致用户会卸载非必要的APP,倒逼管理者必须改变运营策略。随着微信小程序的出现,解决了用户非独立APP不可访问内容的痛点,所以很......
  • 基于单片机设计的激光测距仪(采用XKC-Kl200模块)
    一、前言随着科技的不断进步和应用需求的增加,测距仪成为了许多领域必备的工具之一。传统的测距仪价格昂贵、体积庞大,使用起来不够方便。本项目采用STC89C52单片机作为主控芯片,结合XKC-KL200激光测距模块和LCD1602显示器,实现了一个简易且高效的激光测距仪。这个测距仪可以帮助用户快......
  • C语言-rewind函数
     ......
  • 复旦大学的第一本大模型中文书真的不要太强-《大规模语言模型 从理论到实践》
    复旦大学NLP实验室的大牛教授们出书了!国内第一本全面介绍大语言模型的中文书,让普通人也能感受AI的魔力!......
  • Metasploit Pro 4.22.4-2024091601 发布下载,新增功能概览
    MetasploitPro4.22.4-2024091601发布下载,新增功能概览MetasploitPro4.22.4-2024091601(Linux,Windows)-专业渗透测试框架Rapid7Penetrationtesting,releaseSep16,2024请访问原文链接:https://sysin.org/blog/metasploit-pro-4/,查看最新版。原创作品,转载请保留出......
  • 如何解决"Warning: Cannot modify header information - headers already sent"问题
    解决方法检查早期输出确保脚本在发送任何HTTP头前没有进行任何输出,包括空格、换行符或字符串。使用输出缓冲控制函数在脚本开始处使用ob_start()来启动输出缓冲。在需要发送HTTP头之前,确保输出缓冲已经被适当管理,例如使用ob_end_flush()来结束并输出缓冲内容。清......
  • Shiro-550—漏洞分析(CVE-2016-4437)
    目录漏洞原理源码分析加密过程解密过程漏洞复现漏洞原理Shiro-550(CVE-2016-4437)反序列化漏洞在调试cookie加密过程的时候发现开发者将AES-CBC用来加密的密钥硬编码了,并且所以导致我们拿到密钥后可以精心构造恶意payload替换cookie,然后让后台最后解密的时候进行反序列化我们的......
  • 【2024-09-19】人往高走
    20:00当华美的叶片落尽,生命的脉络才历历可见。                                              ——聂鲁达今天下午帮二宝挂了眼科号,原因是她近期频繁地眨眼睛。不只是近期,早......