ArrayBlockingQueue
    底层基于数组,具有阻塞的功能,FIFO,生产消费者模式
    Queue提供的api
    image.png

    add,offer 插入元素
    remove,poll 取元素
    element,peek 查询元素

    抛异常 阻塞 超时 返回特殊值(一般情况都是boolean,null)

    插入元素(遇到慢的情况) add put offer offer

    取元素(删除取出的元素) remove take poll poll

    查询元素(对队列没有影响) element peek

    ArrayBlockingQueue结构

    items
    存放元素
    takeIndex
    取元素的指针,记录下一次出队的位置
    putIndex
    存元素的指针,记录下一次入队的位置 (指向下一个空位置)
    两个指针可以形成一个环形数组,take追着put跑,当put到数组的最大值的时候会将putIndex指向下标为0的节点,takeIndex也是从下标为0的节点开始处理,这样会重复利用数组的节点,当takeIndex==putIndex说明元素被取空了或者满了
    count
    计算元素个数
    ReentrantLook
    ArrayBlockingQueue中维护了一把锁,入队和出队是相互阻塞的
    Condition
    有两个Condition是通过ReentrantLook来获取的,这里使用到await和signal,lock.newCondition返回的对象await必须要用同一个对象signal唤醒
    notEmpty 出队的对象,说明队列不为空,唤醒的是take
    notFull 入队的对象,说明队列

    image.png

    使用

    1. @Service
    2. public class ArrayBlockingQueueTest {
    3. private static ArrayBlockingQueue<String> arrayBlockingQueue = new ArrayBlockingQueue<>(10);
    4. @Scheduled(cron="0/5 * * * * ? ")
    5. public void test(){
    6. //放数据
    7. try {
    8. arrayBlockingQueue.put(new Date().toString());
    9. } catch (InterruptedException e) {
    10. e.printStackTrace();
    11. }
    12. }
    13. @PostConstruct
    14. public void init(){
    15. new Thread(() -> {
    16. while (true){
    17. try {
    18. // 取数据
    19. String take = arrayBlockingQueue.take();
    20. System.out.println("拿到数据" + take);
    21. } catch (InterruptedException e) {
    22. e.printStackTrace();
    23. }
    24. System.out.println("执行");
    25. }
    26. }).start();
    27. }
    28. }