美文网首页Java 杂谈java多线程
Java 多线程(十):DelayQueue、PriorityB

Java 多线程(十):DelayQueue、PriorityB

作者: 聪明的奇瑞 | 来源:发表于2018-07-11 00:41 被阅读26次

    PriorityBlockingQueue

    • PriorityBlockingQueue 是一个支持优先级的无边界阻塞队列,默认情况下采用自然顺序排列,也可以通过比较器 Comparator 指定排序规则
    public class Person {
        private String name;
        private int age;
    
        public Person(String name, int age) {
            this.name = name;
            this.age = age;
        }
    
        public String getName() {
            return name;
        }
    
        public int getAge() {
            return age;
        }
    
        @Override
        public String toString() {
            return "Person{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    '}';
        }
    }
    
    
    public class Main {
        public static void main(String[] args) throws Exception{
            PriorityBlockingQueue<Person> queue = new PriorityBlockingQueue<Person>(3,((o1, o2) -> {
                if(o1.getAge() > o2.getAge())
                    return 1;
                else if(o1.getAge()<o2.getAge())
                    return -1;
                return 0;
            }));
            queue.put(new Person("a",3));
            queue.put(new Person("b",1));
            queue.put(new Person("c",2));
            System.out.println(queue.take());
            System.out.println(queue.take());
            System.out.println(queue.take());
        }
    }
    

    DelayQueue

    • DelayQueue 是一个支持延迟获取元素的无边界阻塞队列,列头的元素是最先到期的元素,若无元素到期,即使队列有元素,也无法从列头获取元素
    • 放入队列的元素需要实现 Delayed 接口,Delayed 接口继承了 Comparable 接口,所以需要实现下面两个方法:
      • long getDelay(TimeUnit unit):获取元素剩余的延迟时间,当返回值小于 0 时,则视为到期
      • int compareTo(Delayed o):用于延迟队列内部比较排序
    public class DelayedElement implements Delayed {
    
        private long delay; //延迟时间
        private long expire;  //到期时间
        private int number;   //值
        private long now; //创建时间
    
        public DelayedElement(long delay, int number) {
            this.delay = delay;
            this.number = number;
            expire = System.currentTimeMillis() + delay;    //到期时间 = 当前时间+延迟时间
            now = System.currentTimeMillis();
        }
    
        /**
         * 需要实现的接口,获得延迟时间   用过期时间-当前时间
         */
        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(this.expire - System.currentTimeMillis(), TimeUnit.MILLISECONDS);
        }
    
        /**
         * 用于延迟队列内部比较排序   
         */
        @Override
        public int compareTo(Delayed o) {
            DelayedElement delayedElement = (DelayedElement) o;
            return this.number - ((DelayedElement) o).getNumber();
        }
    
        public int getNumber() {
            return number;
        }
    
        @Override
        public String toString() {
            return "DelayedElement{" +
                    "delay=" + delay +
                    ", expire=" + expire +
                    ", number=" + number +
                    ", now=" + now +
                    '}';
        }
    }
    
    public class Main2 {
        public static void main(String[] args) throws Exception{
            DelayQueue delayQueue = new DelayQueue();
    
           DelayedElement d1 = new DelayedElement(1000,1);
           DelayedElement d2 = new DelayedElement(1000,3);
           DelayedElement d3 = new DelayedElement(1000,2);
    
           delayQueue.put(d1);
           delayQueue.put(d2);
           delayQueue.put(d3);
    
           System.out.println(delayQueue.take());
            System.out.println(delayQueue.take());
            System.out.println(delayQueue.take());
        }
    }
    

    SynchronousQueue

    • SynchronousQueue 实际上不是一个真正的队列,因为它并不能存储元素,因此 put 和 take 会一直阻塞当前线程,每一个插入操作都必须等待另一个线程的删除操作
    public class Main2 {
        public static void main(String[] args) {
            SynchronousQueue<String> syncQueue = new SynchronousQueue<>();
    
            new Thread(()->{
                try {
                    syncQueue.put("a");
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
    
            new Thread(()->{
                try {
                    System.out.println(syncQueue.take());
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }).start();
        }
    }
    

    相关文章

      网友评论

        本文标题:Java 多线程(十):DelayQueue、PriorityB

        本文链接:https://www.haomeiwen.com/subject/evdcpftx.html