• JUC之阻塞队列(BlockingQueue)基础


    阻塞队列

    阻塞队列(BlockingQueue)是一个支持两个附加操作的队列。这两个附加的操作支持阻塞的插入和移除方法。

    阻塞队列常用于生产者和消费者的场景:

    当队列为空的,从队列中获取元素的操作将会阻塞;

    当队列为满的,从队列中添加元素的操作将会阻塞;

    所谓的阻塞:在某些情况下会挂起线程(即阻塞),一旦条件满足,被挂起的线程又会自动被唤起。

    阻塞队列的用处:不需要我们关心什么时候需要阻塞线程,什么时候需要唤醒线程。

    BlockingQueue的实现类(比较常用):

    1. ArrayBlockingQueue:有数组结构组成的有界阻塞队列;
    2. LinkedBlockingQueue:有链表结构组成的有界(但大小默认值为Integer.MAX_VALUE)阻塞队列;
    3. SynchronousQueue:不存储元素的阻塞队列,即单个元素的队列。
    方法类型 抛出异常 布尔值 阻塞 超时
    插入 add(e) offer(e) put(e) offer(e,time,TimeUnit)
    删除 remove() poll() take() poll(time,TimeUnit);
    检查 element() peek() 不可用 不可用

    抛出异常

    1. 当阻塞队列满时,再往队列里add插入元素会抛出IllegalStateException:Queue full
    2. 当队列为空时,再往队列中remove移除元素会抛NoSuchElementException
    ArrayBlockingQueue<String> queue = new ArrayBlockingQueue<>(3);
    System.out.println(queue.add("a"));
    System.out.println(queue.add("a"));
    System.out.println(queue.add("a"));
    
    System.out.println(queue.remove());
    System.out.println(queue.remove());
    System.out.println(queue.remove());
    System.out.println(queue.remove());
    

    布尔值

    1. 插入方法,成功未true,失败为false
    2. 移除方法,成功返回队列的元素,队列没有就返回null
    System.out.println(queue.offer("a"));
    System.out.println(queue.offer("a"));
    System.out.println(queue.offer("a"));
    
    System.out.println(queue.poll());
    System.out.println(queue.poll());
    System.out.println(queue.poll());
    System.out.println(queue.poll());
    

    阻塞

    1. 当阻塞队列满时,生产者线程继续往队列里put元素,队列会一直阻塞生产者线程直到put数据or响应中断退出
    2. 当阻塞队列空时,消费者线程试图从队列里take元素,队列会一直阻塞消费者线程直到队列可用
    queue.put("a");
    queue.put("a");
    queue.put("a");
    //queue.put("a");
    System.out.println(queue.take());
    System.out.println(queue.take());
    System.out.println(queue.take());
    //System.out.println(queue.take());
    

    超时

    1. 当阻塞队列满时,队列会阻塞生产者线程一定时间,超过限制后生产者线程会退出
    queue.offer("a");
    queue.offer("a");
    queue.offer("a");
    queue.offer("a",1L, TimeUnit.SECONDS);
    
    System.out.println(queue.poll());
    System.out.println(queue.poll());
    System.out.println(queue.poll());
    queue.poll(1L,TimeUnit.SECONDS);
    

    注意:

    如果是无界阻塞队列,队列不可能会出现满的情况,所以使用put或offer方法永远不会被阻塞,而且使用offer方法时,该方法永远返回true

  • 相关阅读:
    Node 命令行工具 commander.js 快速上手
    使用 express 极简处理前端路由的 history 模式问题
    在博客中插入希沃白板课件
    休息一下(屏幕提醒)
    vue htmlWebpackPlugin.options.title 标题设置
    使用 docker 部署 elasticsearch 并安装 ik 中文分词器
    .NET 中的计时 tick 是多长?
    剑指offer队列的最大值(主队列+辅助队列)
    Golang垃圾回收原理解析
    Golangchannel底层实现精要
  • 原文地址:https://www.cnblogs.com/xbhog/p/15793171.html
Copyright © 2020-2023  润新知