• 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<Integer> queue = new PriorityQueue<Integer>(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<Integer> queue = new ArrayBlockingQueue<Integer>(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();
    }
    }
    }
    }
    }

  • 相关阅读:
    拓扑编号
    奇怪的梦境
    奖金
    最优布线问题
    亲戚
    最小花费
    Dijkstra算法 最短路径 (部分)
    Floyed算法 最短路径
    P1164 小A点菜(背包方案数模板)
    P1049 装箱问题
  • 原文地址:https://www.cnblogs.com/farmer-lau/p/10373560.html
Copyright © 2020-2023  润新知