zoukankan      html  css  js  c++  java
  • java里面的队列

    非阻塞无界队列

    ConcurrentLinkedQueue

     

      public static void main(String[] args) throws InterruptedException {
            ConcurrentLinkedQueue queue=new ConcurrentLinkedQueue();
            queue.add(1);//内部调用offer
            queue.offer(1);
            queue.remove();//如果队里为空会报java.util.NoSuchElementException
            queue.peek();//拿队列元素 但不删除
    queue.poll();获取队列元素并删除如果没有则是null }

    阻塞队列

    阻塞队列 指的是像队列添加元素 如果满了则阻塞等待队列容器有空间再往里面添加元素。或则 队列为空往容器里面取元素 则阻塞等待队列里面有元素取出‘

    方法。

    JDK7提供了7个阻塞队列

    • ArrayBlockingQueue :一个由数组结构组成的有界阻塞队列。
    • LinkedBlockingQueue :一个由链表结构组成的有界阻塞队列。
    • PriorityBlockingQueue :一个支持优先级排序的无界阻塞队列。
    • DelayQueue:支持延时的队列
    • SynchronousQueue:一个不存储元素的阻塞队列。
    • LinkedTransferQueue:一个由链表结构组成的无界阻塞队列。
    • LinkedBlockingDeque:一个由链表结构组成的双向阻塞队列。

    常用方法

    添加

    boolean add 如果队列满了add则抛出异常

    boolean offer 如果队列满了 可以设置阻塞时间

    void put 如果队列满了则一直阻塞

    获取队列元素并移除

    Integer remove  如果队列为空 则抛出异常

    Integer poll   如果队列为空可返回null 设置阻塞时间

    void take  如果队列为空 一直阻塞

    获取队列元素不移除

    element  如果队列为空抛出异常

     peek 如果队列为空则获的null

    ArrayBlockingQueue

    使用数组实现 先进先出的队列。提供2个构造参数,默认不保证访问者公平的访问队列,就是调用添加方法 默认不是按先阻塞的线程 先存。  或者移除 不是按先阻塞的线程先获取并移除 可以通过ArrayBlockingQueue fairQueue = new  ArrayBlockingQueue(1000,true); 设置为true保证公平性

    LinkedBlockingQueue

    使用链表实现 跟ArrayBolckingQueue的区别则是

    ArrayBolckingQueue:

      1.一个是生产者和消费者使用的是同一把锁。

      2.初始化必须指定大小

           3.插入时直接将对象插入

    LinkedBlockingQueue:

      1.则是使用生产者使用一把锁 消费者使用一把锁

           2.可以不指定容器大小 但是最大值是Integer.MAX_VALUE

           3.插入时将对象转为Node插入

    PriorityBlockingQueue

     拥有优先级排序的无界队列。需要实现comparator接口。

    public class Student implements Comparable<Student> {
        public Integer age;
        public  Student(Integer age){
            this.age=age;
        }
        @Override
        public int compareTo(Student stu) {
            if(age < stu.age)
            {
                return -1;
            }else
            {
                if(age > stu.age)
                {
                    return 1;
                }else
                {
                    return 0;
                }
            }
        }
    }
       PriorityBlockingQueue<Student> queue=new PriorityBlockingQueue<Student>();
            queue.add(new Student(1));
            queue.add(new Student(3));
            queue.add(new Student(5));
            queue.add(new Student(0));
            System.out.println(queue.poll().age);
            System.out.println(queue.poll().age);
            System.out.println(queue.poll().age);
            System.out.println(queue.poll().age);

    输出

    0
    1
    3
    5

    DelayQueue

    支持延时的无界阻塞队列 需要实现delay接口

    public class Message implements Delayed {
        private final long expire;  //到期时间
        private final String msg;   //数据
    
        public Message( long expire, String msg) {
            this.expire = expire;
            this.msg = msg;
        }
    
        /**
         * 需要实现的接口,获得延迟时间   用过期时间-当前时间
         * @param unit
         * @return
         */
        @Override
        public long getDelay(TimeUnit unit) {
            return unit.convert(this.expire - System.currentTimeMillis() , TimeUnit.MILLISECONDS);
        }
    
        @Override
        public int compareTo(Delayed other) {
            return (int) (this.getDelay(TimeUnit.MILLISECONDS) -other.getDelay(TimeUnit.MILLISECONDS));
        }
    
        public long getExpire() {
            return expire;
        }
    
        public String getMsg() {
            return msg;
        }
    }
        public static void main(String[] args) throws InterruptedException {
            DelayQueue<Message> queue=new DelayQueue<Message>();
    
            Calendar nowTime = Calendar.getInstance();
            nowTime.add(Calendar.MINUTE, 1);
            Message message=new Message(nowTime.getTime().getTime(),"哈哈哈");
            queue.add(message);
            nowTime = Calendar.getInstance();
            nowTime.add(Calendar.MINUTE, 3);
             message=new Message(nowTime.getTime().getTime(),"哈哈哈3");
            queue.add(message);
            nowTime = Calendar.getInstance();
            nowTime.add(Calendar.MINUTE, 2);
             message=new Message(nowTime.getTime().getTime(),"哈哈哈2");
            queue.add(message);
            while (true) {
              Message message1=   queue.take();
              System.out.println(message1.getMsg());
            }
        }

    SynchronousQueue

      没有容量的队列。生产者生产立即推送给消费者

     public static void main(String[] args) throws InterruptedException {
            SynchronousQueue<String> queue=new SynchronousQueue<String>();
            new Thread(new Runnable() {
                @Override
                public void run() {
                    int i=0;
                   while (true){
                       try {
                           Thread.sleep(1000);
                           queue.put(Integer.toString(i));
                       } catch (Exception e) {
                           e.printStackTrace();
                       }
                       i++;
                   }
                }
            }).start();
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    while (true){
                        try {
                            Thread.sleep(2000);
                            System.out.println(queue.take().toString());
                        } catch (Exception e) {
                            e.printStackTrace();
                        } {
    
                        }
                    }
    
                }
            }).start();
        }

    LinkedTransferQueue

    LinkedTransferQueue是一个由链表结构组成的无界阻塞TransferQueue队列。相对于其他阻塞队列LinkedTransferQueue多了tryTransfer和transfer方法。

    1. transfer(E e):若当前存在一个正在等待获取的消费者线程,即立刻移交之;否则,会插入当前元素e到队列尾部,并且等待进入阻塞状态,到有消费者线程取走该元素。
         2. tryTransfer(E e):若当前存在一个正在等待获取的消费者线程(使用take()或者poll()函数),使用该方法会即刻转移/传输对象元素e;若不存在,则返回false,并且不进入队列。这是一个不阻塞的操作。

    LinkedBlockingDeque

    LinkedBlockingDeque是一个由链表结构组成的双向阻塞队列。所谓双向队列指的你可以从队列的两端插入和移出元素。双端队列因为多了一个操作队列的入口,在多线程同时入队时,也就减少了一半的竞争。相比其他的阻塞队列,LinkedBlockingDeque多了addFirst,addLast,offerFirst,offerLast,peekFirst,peekLast等方法

  • 相关阅读:
    摩托罗拉SE4500 德州仪器TI Omap37xx/AM3715/DM3730/AM3530 wince6.0/Windows Mobile 6.5平台 二维软解调试记录及相关解释
    摩托罗拉SE4500 三星 S3C6410 Wince6.0平台软解码调试记录以及驱动相关问题解释
    MSM8909+Android5.1.1之系统烧录
    PIC16F914SEG脚中电路图注意事项
    PIC16F914ADC模块采集数据转换
    PIC914AD模块使用记录
    PIC914 LCDCON液晶控制寄存器用法
    PIC914SEG设置方法
    示波器用法
    检测单片机是否启动
  • 原文地址:https://www.cnblogs.com/LQBlog/p/8733764.html
Copyright © 2011-2022 走看看