java队列

队列

队列是一种特殊的线性表,限定只能在表的一端进行插入(队尾),而在另一端进行取值(也可以同时删除元素)的操作(对头),特点是“先进后出”。

队列Queue是Collection的子接口,继承了Collection的方法。

队列的分类

  • 按功能分类

    • 普通队列

      普通队列(Queue)是指实现了先进先出的基本队列

      常见实现类

      ArrayBlockingQueue是用数组实现的普通队列

      LinkedBlockingQueue是使用链表实现的普通队列

      常用方法

      offer():添加元素,如果队列已满直接返回false,队列未满直接插入并返回ture;

      poll():删除并返回对头元素,当队列为空返回null;

      add():添加元素,此方法是对offer方法的简单封装,如果队列已满,抛出IllegalStateException异常;

      remove():直接删除队头元素;

      peek():查询队头元素,但不会进行删除;

      示例

      public class NormalQueue {
          public static void main(String[] args) {
              //产生队列
              Queue<String> queue = new LinkedBlockingDeque<>();
              //添加元素
              queue.offer("紫衫龙王");
              queue.offer("青翼蝠王");
              queue.offer("金毛狮王");
              queue.offer("白眉鹰王");
              //队列遍历,如果还有元素则继续循坏
              while (!queue.isEmpty()) {
              //取出表头元素,并做删除处理
                 String str= queue.poll();
                  System.out.println("取出"+str+"现有"+queue);
              }
          }
      }
      
    • 双端队列

      双端队列(Deque)是指队列的头部和尾部都可以同时入队和出队的数据结构。

      示例:

          public static void main(String[] args) {
              //创建双端队列对象
              ArrayDeque<Integer> deque=new ArrayDeque<>();
              //向队列添加元素
              deque.offer(1);
              deque.offer(2);
              //向队头添加元素
              deque.offerFirst(3);
              //向队尾添加元素
              deque.offerLast(4);
              while (!deque.isEmpty()){
                  //从队头取出并移除元素
                 Integer obj= deque.poll();
                  System.out.println(obj);//结果 3 1 2 4
              }
          }
      
    • 优先队列

      优先队列(PriorityQueue)是一种特殊的队列,它并不是先进先出

      public class PriorityTest {
          public static void main(String[] args) {
              //创建优先队列对象,并通过比较器确定优先级大小
              PriorityQueue<Student> priorityQueue = new PriorityQueue(new Comparator<Student>() {
                  @Override
                  public int compare(Student o1, Student o2) {
                      return o2.getGrade()- o1.getGrade();
                  }
              });
              //向队列加入元素
              priorityQueue.offer(new Student(3,"张三",90));
              priorityQueue.offer(new Student(1,"李四",96));
              priorityQueue.offer(new Student(4,"刘五",54));
              priorityQueue.offer(new Student(2,"赵六",76));
         while (!priorityQueue.isEmpty()){
             //从队列中取出元素
             Student s = priorityQueue.poll();
             System.out.println(s);
         }
          }
      }
      
  • 按大小分类

    • 有界队列

      是指有固定大小的队列,比如:设定了固定大小的ArrayBlockingQueue,又或者大小为0的SynchronousQueue。

    • 无界队列

      指的是没有设置固定大小的队列,队列大小随元素多少而增加。比如:ConcurrentLinkedQueue和PriorityQueue

  • 按是否阻塞分类

    • 阻塞队列

      阻塞队列(BlockingQueue)提供了可阻塞的put和take方法。如果队列满了put方法会被阻塞等到有空间可用再将元素插入;如果队列是空的,那么take方法也会阻塞,直到有元素可用。

      阻塞队列名称中,一般包含BlockingQueue。比如ArrayBlockingQueue、LinkedBlockingQueue。

      示例

          public static void main(String[] args) {
              //创建阻塞有界队列,长度为5
              ArrayBlockingQueue<Integer> blockingQueue = new ArrayBlockingQueue<>(5);
              //向队列加入元素
              new Thread() {
                  public void run() {
                      for (int i = 0; i < 10; i++) {
                          try {
                              //向队列加入元素,如果队列满,则阻塞
                              blockingQueue.put(i);
      //                        System.out.println(blockingQueue);
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                      }
                  }
              }.start();
      
              new Thread() {
                  public void run() {
                      while (true) {
                          try {
                              Integer x = blockingQueue.poll();
                              Thread.sleep(1000);
                              System.out.println("取出:" + x + "    " + blockingQueue);
                          } catch (InterruptedException e) {
                              e.printStackTrace();
                          }
                      }
                  }
              }.start();
          }
      
    • 非阻塞队列

      非阻塞队列也就是普通队列,它的名字中不会包含BlockingQueue关键字,并且它不会包含put和take方法,当队列满了之后如果还有新元素入列会直接返回错误,并不会阻塞的等待着添加元素。

      非阻塞队列的典型代表是ConcurrentLinkedQueue和PriorityQueue

      在并发编程中,一般推荐使用阻塞队列,这样实现可以尽量地避免程序出现意外的错误。阻塞队列使用最经典的场景就是scoket客户端数据的读取和解析,读取数据的线程不断将数据放入队列,然后解析线程不断从队列取数据解析。例如:秒杀系统

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值