zoukankan      html  css  js  c++  java
  • DelayQueue与ProirityBlockingQueue

      DelayQueue是一个无界队列,只有在延迟期满的时候,才可以取出元素。该队列的头部存储的延期期满了后保存时间最长的元素。

      DelayQueue阻塞队列在我们系统开发中也常常会用到,例如:缓存系统的设计,缓存中的对象,超过了空闲时间,需要从缓存中移出;任务调度系统,能够准确把握任务的执行时间。我们可能需要通过线程处理很多时间上要求很严格的数据,如果使用普通的线程,我们就需要遍历所有的对象,一个一个的检 查看数据是否过期等,首先这样在执行上的效率不会太高,其次就是这种设计的风格也大大的影响了数据的精度。一个需要12:00点执行的任务可能12:01 才执行,这样对数据要求很高的系统有更大的弊端。由此我们可以使用DelayQueue。

      为了具有调用行为,存放到DelayDeque的元素必须继承Delayed接口。Delayed接口使对象成为延迟对象,它使存放在DelayQueue类中的对象具有了激活日期。

      该接口强制执行下列两个方法。

      CompareTo(Delayed o):Delayed接口继承了Comparable接口,该方法是进行队列中元素的排序。

      getDelay(TimeUnit unit):这个方法返回到激活日期的剩余时间,时间单位由单位参数指定。

      下面给出一个简单的案例,网吧与网民上网,网民交了钱后开始上网,当上网时间到了,网吧结束网民上网。

    /**
     * 网民实体类
     */
    public class Netizen implements Delayed {
        
        //身份证
        private Long id;
        //姓名
        private String name;
        //上网截至时间
        private Long endTime;
        //定义时间工具类
        private TimeUnit timeUnit = TimeUnit.SECONDS;
        
        public Netizen(Long id, String name, Long endTime) {
            super();
            this.id = id;
            this.name = name;
            this.endTime = endTime;
        }
        public Long getId() {
            return id;
        }
        public void setId(Long id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public Long getEndTime() {
            return endTime;
        }
        public void setEndTime(Long endTime) {
            this.endTime = endTime;
        }
        //元素相互批较排序
        public int compareTo(Delayed o) {
            Netizen netizen=(Netizen) o;
            return this.getDelay(this.timeUnit)-netizen.getDelay(this.timeUnit)>0?1:0;
        }
        //判断是否到了截至时间
        public long getDelay(TimeUnit unit) {
            
            return endTime-System.currentTimeMillis();
        }
    }
    /**
     * 网吧实体类
     * @author szekinwin
     *
     */
    public class InternetBar implements Runnable{
        
        private DelayQueue<Netizen> queue=new DelayQueue<Netizen>();
        
        //网民上网
        public void startComputer(Long id,String name,int money){
            
            Netizen netizen=new Netizen(id, name, 1000*money+System.currentTimeMillis());
            
            System.out.println("网名"+name+"开始上网计费...");
            
            queue.add(netizen);
            
        }
        //网民上网时间结束
        public void overComputer(Netizen netizen){
            
            System.out.println("网名"+netizen.getName()+"上网时间结束...");
            
        }
      //检查上网时间是否到期
    public void run() { while(true){ try { Netizen netizen=queue.take(); overComputer(netizen); } catch (InterruptedException e) { e.printStackTrace(); } } } public static void main(String[]args){ InternetBar internatBar=new InternetBar();
         //创建三个网民 internatBar.startComputer(
    1L, "n1", 3); internatBar.startComputer(2L, "n2", 5); internatBar.startComputer(3L, "n3", 7); Thread t1=new Thread(internatBar); t1.start(); } }

      输出结果如下:

      

      接下来总结一下PriorityBlockingQueue优先级队列,存放在队列中的元素必须实现Comparable接口,重写compareTo()方法。

    public class Task implements Comparable<Task>{
    
        private int id;
        
        private String name;
        
        public int getId() {
            return id;
        }
    
        public void setId(int id) {
            this.id = id;
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public int compareTo(Task o) {
            return this.id > o.id?1:(this.id < o.id?-1:0);
        }
        
        public String toString(){
            return this.id + "," + this.name;
        }
    
    }
    public class PriorityQueueDemo {
        
        public static void main(String[]args) throws InterruptedException{
            
            PriorityBlockingQueue<Task> queue=new PriorityBlockingQueue<Task>();
            Task t1=new Task();
            t1.setId(5);
            t1.setName("p1");
            Task t2=new Task();
            t2.setId(3);
            t2.setName("p2");
            Task t3=new Task();
            t3.setId(7);
            t3.setName("p3");
            queue.add(t1);
            queue.add(t2);
            queue.add(t3);
            System.out.println(queue.toString());
            System.out.println(queue.take().getId());
        }
    }

      输出结果如下:也就是说队列中的元素是根据元素的ID进行排序的。ID值低的优先级高。

      

      参考网址:http://www.cnblogs.com/wxgblogs/p/5464867.html

  • 相关阅读:
    mysql5.7一颗B+树可以存放多少行数据?为什么使用B+树而不是B树?
    mysql5.7的锁:乐观锁/共享锁、互斥/排他锁、意向锁、记录锁、行锁/表锁、间隙锁、临界锁、插入意向锁、自增锁、空间索引预测锁、隐式锁
    mysql5.7事务的原理和MVCC,redo log与bin log的区别
    mysql5.7 Buffer Pool特性介绍。innodb三大特性:双写缓冲区、Buffer Pool、AHI(自适应HASH索引)
    mysql5.7 innodb数据字典
    mysql5.7系统表空间和独立表空间,断,组,区,页的概念,innodb双写缓冲区
    mysql5.7行数据存储格式
    mysql5.7全局考虑性能化,SQL优化的最后一步:profile性能分析
    mysql5.7innodb引擎底层分析:子查询种类回顾
    mysql5.7强制指定驱动表与被驱动表straight_join
  • 原文地址:https://www.cnblogs.com/gdpuzxs/p/6748728.html
Copyright © 2011-2022 走看看