java中的原生队列

    技术2022-07-11  123

    java中的原生队列

    1.非阻塞   1.1,PriorityQueue:优先级队列,存入的元素可以实现Comparable,从而按照自定义的顺序去执行   1.2,LinkedList:双向链表,实现了Dequeue接口 2.阻塞   2.1,ArrayBlockingQueue:数组队列     a.底层是数组,读取快,增删慢     b.指定公平性(是否让等待最长的队列先执行),默认不公平     public ArrayBlockingQueue(int capacity, boolean fair),fair:公平     c.创建时必须指定大小     d.先进先出(公平性是另一个范畴,公平性是相对于队列的消费者而言的)   2.2,LinkedBlockingQueue:链表队列     a.底层是双向链表,增删快,读取慢     b.可以不指定容量大小,默认Integer.MAX_VALUE     c.没有公平性一说     d.先进先出(公平性是另一个范畴,公平性是相对于队列的消费者而言的)   2.3,PriorityBlockingQueue:优先级队列   a.需要传入一个Comparable的实现类,即自定义优先级   b.此队列是无界队列,但是可以指定初始容量,大最大容量没有限制,插入元素不 会被阻塞   2.4,DelayQueue:延时队列     a.无界队列,插入元素不会被阻塞     b.只有当指定的延时时间到了才能从队列中获得元素

    3.方法   3.1.阻塞队列和非阻塞队列的通用方法     3.1.1增       add(E e):将元素e插入到队列末尾,如果插入成功,则返回true;如果插入失败(即 队列已满),则会抛出异常;       offer(E e):将元素e插入到队列末尾,如果插入成功,则返回true;如果插入失败(即队列已满),则返回false;     3.1.2删       remove():移除队首元素,若移除成功,则返回true;如果移除失败(队列为空),则会抛出异常;       poll():移除并获取队首元素,若成功,则返回队首元素;否则返回null;     3.1.3查       poll():移除并获取队首元素,若成功,则返回队首元素;否则返回null;        peek():获取队首元素,若成功,则返回队首元素;否则返回null

    一般用:offer(E e),poll(),peek()

    2.阻塞队列的特有方法     3.2.1增        put(E e)方法用来向队尾存入元素,如果队列满,则等待       offer(E e,long timeout, TimeUnit unit)方法用来向队尾存入元素,如果队列满,则等待一定的时间,当时间期限达到时,如果还没有插入成功,则返回false;否则返回true;

    3.2.2查       take方法用来从队首取元素,如果队列为空,则等待;       poll(long timeout, TimeUnit unit)方法用来从队首取元素,如果队列空,则等待一定的时间,当时间期限达到时,如果取到,则返回null;否则返回取得的元素;

    4.代码示例     阻塞队列不用自己写线程等待和唤醒的代码,很方便       1.下面先使用Object.wait()和Object.notify()、非阻塞队列实现生产者-消费者模式: class Test { private int queueSize = 10; private PriorityQueue queue = new PriorityQueue(queueSize);

    public static void main(String[] args) { Test test = new Test(); Consumer consumer = test.new Consumer(); try { Thread.sleep(1000l); } catch (InterruptedException e) { e.printStackTrace(); } Producer producer = test.new Producer();

    producer.start(); consumer.start(); }

    class Consumer extends Thread{

    @Override public void run() { consume(); }

    private void consume() { while(true){ synchronized (queue) { while(queue.size() == 0){ try { System.out.println(“队列空,等待数据”); queue.wait(); } catch (InterruptedException e) { e.printStackTrace(); queue.notify(); } } queue.poll(); //每次移走队首元素 queue.notify(); System.out.println(“从队列取走一个元素,队列剩余”+queue.size()+“个元素”); } } } }

    class Producer extends Thread{

    @Override public void run() { produce(); }

    private void produce() { while(true){ synchronized (queue) { while(queue.size() == queueSize){ try { System.out.println(“队列满,等待有空余空间”); queue.wait(); } catch (InterruptedException e) { e.printStackTrace(); queue.notify(); } } queue.offer(1); //每次插入一个元素 queue.notify(); System.out.println(“向队列取中插入一个元素,队列剩余空间:”+(queueSize-queue.size())); } } } } }

    2.下面是使用阻塞队列实现的生产者-消费者模式:

    class Test { private int queueSize = 10; private ArrayBlockingQueue queue = new ArrayBlockingQueue(queueSize);

    public static void main(String[] args) { Test test = new Test(); Producer producer = test.new Producer(); Consumer consumer = test.new Consumer();

    producer.start(); consumer.start(); }

    class Consumer extends Thread{

    @Override public void run() { consume(); }

    private void consume() { while(true){ try { queue.take(); System.out.println(“从队列取走一个元素,队列剩余”+queue.size()+“个元素”); } catch (InterruptedException e) { e.printStackTrace(); } } } }

    class Producer extends Thread{

    @Override public void run() { produce(); }

    private void produce() { while(true){ try { queue.put(1); System.out.println(“向队列取中插入一个元素,队列剩余空间:”+(queueSize-queue.size())); } catch (InterruptedException e) { e.printStackTrace(); } } } } }

    Processed: 0.012, SQL: 9