`

读DelayQueen源码

阅读更多
//一个基于二叉堆优先级的延迟取出队列。
//先看构造函数。

public DelayQueue() {}

public DelayQueue(Collection<? extends E> c) {
        this.addAll(c);
    }

 //将collection插入到内部的PriorityQueue中。
 public boolean addAll(Collection<? extends E> c) {
        if (c == null)
            throw new NullPointerException();
        if (c == this)
            throw new IllegalArgumentException();
        boolean modified = false;
        for (E e : c)
            if (add(e))
                modified = true;
        return modified;
    }


    public boolean add(E e) {
        if (offer(e))
            return true;
        else
            throw new IllegalStateException("Queue full");
    }

//插入元素是插入到内部的PriorityQueue中。
    public boolean offer(E e) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            q.offer(e);
	    //如果插入的是头元素(即当前头元素变了)
            if (q.peek() == e) {
	    //将leader线程置为null
                leader = null;
            //唤醒等待的线程
                available.signal();
            }
            return true;
        } finally {
            lock.unlock();
        }
    }

    public boolean offer(E e, long timeout, TimeUnit unit) {
        return offer(e);
    }


    public void put(E e) {
        offer(e);
    }
//获取元素但是并不移出
     public E peek() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
	    //用底层的priorityQueue实现。
            return q.peek();
        } finally {
            lock.unlock();
        }
    }

//获取头元素如果头元素为空或者还没有到出列时间返回null。
     public E poll() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
	   //获取头元素
            E first = q.peek();
	    //如果头元素是空或者获取到的头元素还没有到出列时间返回null
            if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
                return null;
            else
                return q.poll();
        } finally {
            lock.unlock();
        }
    }

    public E poll(long timeout, TimeUnit unit) throws InterruptedException {
        long nanos = unit.toNanos(timeout);
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            for (;;) {
                E first = q.peek();
		//如果没空
                if (first == null) {
		//超时了返回null
                    if (nanos <= 0)
                        return null;
                    else
		    //挂起当前线程nanos时间
                        nanos = available.awaitNanos(nanos);
                } else {
                    long delay = first.getDelay(TimeUnit.NANOSECONDS);
		    //到时间了可以取出
                    if (delay <= 0)
                        return q.poll();
		    //超时了返回null
                    if (nanos <= 0)
                        return null;
		    //如果等待时间小于出列时间或者leader线程!=null则挂起当前线程
		    if (nanos < delay || leader != null)
                        nanos = available.awaitNanos(nanos);
                    else {
		    //没有其他leader线程则将自己置为leader线程
                        Thread thisThread = Thread.currentThread();
                        leader = thisThread;
                        try {
                            long timeLeft = available.awaitNanos(delay);
                            nanos -= delay - timeLeft;
                        } finally {
			  //如果leader是自己
                            if (leader == thisThread)
                                leader = null;
                        }
                    }
                }
            }
        } finally {
	    //释放锁
            if (leader == null && q.peek() != null)
                available.signal();
            lock.unlock();
        }
    }

//可阻塞的获取队列头结点
 public E take() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            for (;;) {
                E first = q.peek();
		//没有获取到则等待
                if (first == null)
                    available.await();
                else {
                    long delay = first.getDelay(TimeUnit.NANOSECONDS);
                    //到达队列出列时间返回
		    if (delay <= 0)
                        return q.poll();
		    //如果leader不等于null阻塞当前线程让leader线程取走当前元素
                    else if (leader != null)
                        available.await();
                    else {
                        Thread thisThread = Thread.currentThread();
			//当前线程设置为leader
                        leader = thisThread;
                        try {
			    //等待delay时间被唤醒
                            available.awaitNanos(delay);
                        } finally {
			   //醒来之后如果我是leader让其他线程变为leader。
                            if (leader == thisThread)
                                leader = null;
                        }
                    }
                }
            }
        } finally {
	    //如果leader为空并且有头唤醒其他线程。
            if (leader == null && q.peek() != null)
                available.signal();
            lock.unlock();
        }
    }


    /**leader线程是当前正在获取头节点的线程。在offer的时候如果插入的元素变为了头结点,
    此时将leader置为null,重新竞争leader。
    DelayQueen内部使用的是一个PriorityQueen类实现,所以可以保证插入顺序的优先级。
    然后根据实现Delayed接口的getDelay方法来获取元素是否已经到出列时间。
    */

//获取队列长度
    public int size() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            return q.size();
        } finally {
            lock.unlock();
        }
    }
//获取容量(没有容量限制所以返回integer最大值)
public int remainingCapacity() {
        return Integer.MAX_VALUE;
    }

//移除元素
public boolean remove(Object o) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            return q.remove(o);
        } finally {
            lock.unlock();
        }
    }


 public Object[] toArray() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            return q.toArray();
        } finally {
            lock.unlock();
        }
    }

public <T> T[] toArray(T[] a) {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            return q.toArray(a);
        } finally {
            lock.unlock();
        }
    }
//移出队列中的可用元素并将他们封装到collection中
 public int drainTo(Collection<? super E> c) {
        if (c == null)
            throw new NullPointerException();
        if (c == this)
            throw new IllegalArgumentException();
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            int n = 0;
            for (;;) {
                E first = q.peek();
                if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
                    break;
                c.add(q.poll());
                ++n;
            }
            return n;
        } finally {
            lock.unlock();
        }
    }
//最多移除maxElements个可用元素到collection中。
public int drainTo(Collection<? super E> c, int maxElements) {
        if (c == null)
            throw new NullPointerException();
        if (c == this)
            throw new IllegalArgumentException();
        if (maxElements <= 0)
            return 0;
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            int n = 0;
            while (n < maxElements) {
                E first = q.peek();
                if (first == null || first.getDelay(TimeUnit.NANOSECONDS) > 0)
                    break;
                c.add(q.poll());
                ++n;
            }
            return n;
        } finally {
            lock.unlock();
        }
    }


分享到:
评论

相关推荐

    小程序源码 语音跟读 (代码+截图)

    小程序源码 语音跟读 (代码+截图)小程序源码 语音跟读 (代码+截图)小程序源码 语音跟读 (代码+截图)小程序源码 语音跟读 (代码+截图)小程序源码 语音跟读 (代码+截图)小程序源码 语音跟读 (代码+截图)小程序源码 ...

    微信小程序开发-绘本跟读案例源码.zip

    在这个“微信小程序开发-绘本跟读案例源码.zip”压缩包中,包含了用于创建一个绘本跟读功能的小程序的全部源代码,非常适合开发者学习和参考。 首先,我们要理解绘本跟读的功能。绘本跟读是教育类应用中常见的一种...

    微信小程序源码(含截图)语音跟读

    微信小程序源码(含截图)语音跟读微信小程序源码(含截图)语音跟读微信小程序源码(含截图)语音跟读微信小程序源码(含截图)语音跟读微信小程序源码(含截图)语音跟读微信小程序源码(含截图)语音跟读微信小...

    英语绘本听跟读小程序源码

    【标题】"英语绘本听跟读小程序源码"所涉及的知识点主要集中在移动应用开发、语音识别技术以及教育软件设计上。这个项目是一款专为英语学习者设计的小程序,其核心功能是听读英语绘本,并且能与智能评分系统对接,...

    易语言源码易语言端口读rs232源码.rar

    易语言源码易语言端口读rs232源码.rar 易语言源码易语言端口读rs232源码.rar 易语言源码易语言端口读rs232源码.rar 易语言源码易语言端口读rs232源码.rar 易语言源码易语言端口读rs232源码.rar 易语言源码...

    小程序&教育培训&悦读神器(源码+截图+源码导入教程和视频).zip

    小程序&教育培训&悦读神器(源码+截图+源码导入教程和视频) 小程序&教育培训&悦读神器(源码+截图+源码导入教程和视频) 小程序&教育培训&悦读神器(源码+截图+源码导入教程和视频)小程序&教育培训&悦读神器(源码...

    微信小程序源码 语音跟读(源码+截图).rar

    免责声明:资料部分来源于合法的互联网渠道收集和整理,部分自己学习积累成果,供大家学习参考与交流。收取的费用仅用于收集和整理资料耗费时间的酬劳。 本人尊重原创作者或出版方,资料版权归原作者或出版方所有,...

    易语言源码易语言读内存例程源码.rar

    易语言源码易语言读内存例程源码.rar 易语言源码易语言读内存例程源码.rar 易语言源码易语言读内存例程源码.rar 易语言源码易语言读内存例程源码.rar 易语言源码易语言读内存例程源码.rar 易语言源码易语言读...

    易语言源码易语言汇编读字节集源码.rar

    易语言源码易语言汇编读字节集源码.rar 易语言源码易语言汇编读字节集源码.rar 易语言源码易语言汇编读字节集源码.rar 易语言源码易语言汇编读字节集源码.rar 易语言源码易语言汇编读字节集源码.rar 易语言源码...

    (微信小程序毕业设计)悦读神器(源码+截图).zip

    (微信小程序毕业设计)悦读神器(源码+截图)(微信小程序毕业设计)悦读神器(源码+截图)(微信小程序毕业设计)悦读神器(源码+截图)(微信小程序毕业设计)悦读神器(源码+截图)(微信小程序毕业设计)悦读神器(源码+截图)(微信...

    微信小程序——语音跟读(截图+源码).zip

    微信小程序——语音跟读(截图+源码).zip 微信小程序——语音跟读(截图+源码).zip 微信小程序——语音跟读(截图+源码).zip 微信小程序——语音跟读(截图+源码).zip 微信小程序——语音跟读(截图+源码).zip ...

    【微信小程序-毕设期末大作业】语音跟读微信小程序源码.zip

    【微信小程序-毕设期末大作业】微信小程序源码 【微信小程序-毕设期末大作业】微信小程序源码 【微信小程序-毕设期末大作业】微信小程序源码 【微信小程序-毕设期末大作业】微信小程序源码 【微信小程序-毕设期末大...

    易语言源码易语言语音报读源码.rar

    易语言源码易语言语音报读源码.rar 易语言源码易语言语音报读源码.rar 易语言源码易语言语音报读源码.rar 易语言源码易语言语音报读源码.rar 易语言源码易语言语音报读源码.rar 易语言源码易语言语音报读源码....

    基于YOLOv5的水表读数系统源码+模型+使用说明.zip

    基于YOLOv5的水表读数系统源码+模型+使用说明.zip基于YOLOv5的水表读数系统源码+模型+使用说明.zip基于YOLOv5的水表读数系统源码+模型+使用说明.zip基于YOLOv5的水表读数系统源码+模型+使用说明.zip基于YOLOv5的水表...

    易语言源码易语言读HEX文件源码.rar

    易语言源码易语言读HEX文件源码.rar 易语言源码易语言读HEX文件源码.rar 易语言源码易语言读HEX文件源码.rar 易语言源码易语言读HEX文件源码.rar 易语言源码易语言读HEX文件源码.rar 易语言源码易语言读HEX文件...

    易语言源码易语言读网页框架源码.rar

    易语言源码易语言读网页框架源码.rar 易语言源码易语言读网页框架源码.rar 易语言源码易语言读网页框架源码.rar 易语言源码易语言读网页框架源码.rar 易语言源码易语言读网页框架源码.rar 易语言源码易语言读...

    易语言源码易语言读网页文件源码.rar

    易语言源码易语言读网页文件源码.rar 易语言源码易语言读网页文件源码.rar 易语言源码易语言读网页文件源码.rar 易语言源码易语言读网页文件源码.rar 易语言源码易语言读网页文件源码.rar 易语言源码易语言读...

    微信小程序源码-悦读神器.zip

    微信小程序源码-悦读神器.zip微信小程序源码-悦读神器.zip微信小程序源码-悦读神器.zip微信小程序源码-悦读神器.zip微信小程序源码-悦读神器.zip微信小程序源码-悦读神器.zip微信小程序源码-悦读神器.zip微信小程序...

    易语言读网页框架源码.rar

    易语言读网页框架源码.rar

    Python 使用Pandas实现数据库的读、写操作 Python源码

    Python 使用Pandas实现数据库的读、写操作 Python源码Python 使用Pandas实现数据库的读、写操作 Python源码Python 使用Pandas实现数据库的读、写操作 Python源码Python 使用Pandas实现数据库的读、写操作 Python源码...

Global site tag (gtag.js) - Google Analytics