阻塞队列

阻塞队列

什么是阻塞队列?

  阻塞队列:从名字可以看出,是一个队列,队列是一个先进先出(FIFO)的数据结构。与普通队列的区别是,多了两个方法,阻塞添加和阻塞删除方法

为什么用阻塞队列?

生产者消费者模式里的wait()和notify()需要我们手动去控制,容易出现死锁等问题。阻塞队列可以帮助我们去控制等待和通知。

img

offer:添加成功时返回true,添加失败返回false,不会阻塞,不会中断

add:添加成功时返回true,添加失败抛出异常,不会阻塞,不会中断

put:没有返回值,会阻塞,会中断

remove:

take 会阻塞,会中断,会一致阻塞,直到取得元素或当前线程中断

poll 会阻塞,会中断,阻塞时间参照timeout.timeUnit,当阻塞时间到了还没取得元素会返回null

package com.blb.demo1;

import java.util.Random;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 阻塞队列
 */
public class BlockingQueueTest {

    public static void main(String[] args) {
        ArrayBlockingQueue<String> blockingQueue = new ArrayBlockingQueue<>(3);

        addMethod(blockingQueue);

    }

    /**
     * add
     * 不会阻塞
     * 添加成功时返回true
     *
     *
     * remove方法
     *
     * @param blockingQueue
     */
    public static void addMethod(BlockingQueue<String> blockingQueue) {

        System.out.println("添加元素\t" + blockingQueue.add("1"));
        System.out.println("添加元素\t" + blockingQueue.add("2"));
        System.out.println("添加元素\t" + blockingQueue.add("3"));
        blockingQueue.forEach(System.out::println);
        System.out.println("队首元素\t" + blockingQueue.element());
        System.out.println("删除元素\t" + blockingQueue.remove());
        System.out.println("队首元素\t" + blockingQueue.element());
        System.out.println("删除元素\t" + blockingQueue.remove());
        System.out.println("队首元素\t" + blockingQueue.element());
        System.out.println("删除元素\t" + blockingQueue.remove());

    }

    /**
     * add
     * 不会阻塞
     * 添加成功时返回true,
     * 如果队列已满则会抛出非法状态异常 IllegalStateException : Queue full
     *
     * @param blockingQueue
     */
    public static void addMethodException(BlockingQueue<String> blockingQueue) {
        System.out.println("添加元素\t" + blockingQueue.add("1"));
        System.out.println("添加元素\t" + blockingQueue.add("2"));
        System.out.println("添加元素\t" + blockingQueue.add("3"));
        System.out.println("添加元素\t" + "添加元素\t" + "添加元素\t" + blockingQueue.add("4"));
        blockingQueue.forEach(System.out::println);
    }

    /**
     * offer
     * 不会阻塞
     * 添加成功返回true
     *
     * pull
     * 会响应中断
     * 会阻塞
     * 阻塞时间参照方法李的参数timeout.timeUnit
     * 当阻塞时间到了还没取得元素会返回null
     *
     * @param blockingQueue
     */
    public static void offerMethod(BlockingQueue<String> blockingQueue) {
        System.out.println("添加元素\t" + "添加元素\t" + blockingQueue.offer("1"));
        System.out.println("添加元素\t" + "添加元素\t" + blockingQueue.offer("2"));
        System.out.println("添加元素\t" + "添加元素\t" + blockingQueue.offer("3"));
        blockingQueue.forEach(System.out::println);
        System.out.println("队首元素" + blockingQueue.peek());
        System.out.println("删除元素" + blockingQueue.poll());
        System.out.println("队首元素" + blockingQueue.peek());
        System.out.println("删除元素" + blockingQueue.poll());
        System.out.println("队首元素" + blockingQueue.peek());
        System.out.println("删除元素" + blockingQueue.poll());


    }

    /**
     * offer
     * 不会阻塞,
     * 添加成功返回true
     * 如果队列已满,则添加失败返回false
     * 不响应中断
     *
     * @param blockingQueue
     */
    public static void offerMethodException(BlockingQueue<String> blockingQueue) {
        System.out.println("添加元素\t" + blockingQueue.offer("1"));
        System.out.println("添加元素\t" + blockingQueue.offer("2"));
        System.out.println("添加元素\t" + blockingQueue.offer("3"));
        System.out.println("添加元素\t" + blockingQueue.offer("4"));
        blockingQueue.forEach(System.out::println);
    }

    /**
     * put
     * 会阻塞会响应中断
     *
     * take
     * 会响应中断
     * 会一致阻塞知道取得元素或当前线程中断
     *
     * @param blockingQueue
     */
    public static void takeMethod(BlockingQueue<String> blockingQueue) {
        try {
            blockingQueue.put("1");
            blockingQueue.put("2");
            blockingQueue.put("3");
            blockingQueue.forEach(System.out::println);
            System.out.println("删除元素"+blockingQueue.take());
            System.out.println("删除元素"+blockingQueue.take());
            System.out.println("删除元素"+blockingQueue.take());
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * put
     * 会阻塞会响应中断
     * 如果队列满了的话会进入阻塞状态
     *
     * @param blockingQueue
     */
    public static void takeMethodException(BlockingQueue<String> blockingQueue) {
        try {
            blockingQueue.put("1");
            blockingQueue.put("2");
            blockingQueue.put("3");
            System.out.println("删除元素"+blockingQueue.take());
            blockingQueue.put("4");
            blockingQueue.forEach(System.out::println);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }
    }


}

posted @ 2023-07-24 02:16  萌萌哒的鸡蛋饼  阅读(15)  评论(0编辑  收藏  举报