阻塞队列

327 阅读2分钟

这是我参与8月更文挑战的第21天,活动详情查看:8月更文挑战

介绍

阻塞队列可以简单的理解为定义一个一定容量的信箱,如果信箱中满了再往信箱中放信会阻塞,如果信箱中为空那么往信箱中拿信会阻塞

阻塞队列常用于生产者和消费者的场景,生产者是往队列里添加元素的线程,消费者是从队列里拿元素的线程。阻塞队列就是生产者存放元素的容器,而消费者也只从容器里拿元素。

image.png

  • 当队列中元素是空的时候,从队列中获取元素的操作会被阻塞
  • 当队列中元素是满的时候,从队列中移除元素的操作会被阻塞

一些阻塞队列

  • ArrayBlockingQueue:由数组结构组成的有界阻塞队列
  • LinkedBlockingQueue:由链表结构组成的有界阻塞队列(大小默认值为Integer.MAX_VALUE)
  • PriorityBlockingQueue::支持优先级排序的无界阻塞队列
  • DelayQueue:使用优先级队列实现的延迟无界阻塞队列
  • SynchronousQueue:不存储元素的阻塞队列,也即单个元素的队列
  • LinkedTransferQueue:由链表结构组成的无界阻塞队列
  • LinkedBlockingDeque:由链表结构组成的双向阻塞队列
方法类型抛出异常特殊值阻塞超时
插入add(e)offer(e)put(e)offer(e,time,unit)
移除remove()poll()take()poll(time,unit)
检查element()peek()不可用不可用

什么是阻塞?

在多线程的情况下,由于某种特殊情况需要挂起线程(就是阻塞),当满足某些条件,这些线程又被唤醒。

阻塞队列的作用?

使我们不需要关心什么时候唤醒线程,什么时候阻塞线程,这些BlockingQueue都帮我们处理了。

抛出异常类型Demo

add:如果队列中元素个数已经满了会抛出异常

import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;

public class Code01_BlockingQueueDemo {
    public static void main(String[] args) {
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(2);
        System.out.println(blockingQueue.add("a"));
        System.out.println(blockingQueue.add("b"));
        System.out.println(blockingQueue.add("c"));
    }
}

测试结果:

true
true
Exception in thread "main" java.lang.IllegalStateException: Queue full
	at java.util.AbstractQueue.add(AbstractQueue.java:98)
	at java.util.concurrent.ArrayBlockingQueue.add(ArrayBlockingQueue.java:312)
	at com.lemon.lesson7_blockingQueue.Code01_BlockingQueueDemo.main(Code01_BlockingQueueDemo.java:11)

remove:如果队列中没有元素会抛出异常

public class Code01_BlockingQueueDemo {
    public static void main(String[] args) {
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(2);
        System.out.println(blockingQueue.add("a"));
        System.out.println(blockingQueue.add("b"));
        blockingQueue.remove();
        blockingQueue.remove();
        blockingQueue.remove();
    }
}

element:如果队列中没有元素会抛出异常

public class Code01_BlockingQueueDemo {
    public static void main(String[] args) {
        BlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(2);
        blockingQueue.element();
    }
}