阻塞队列

阻塞队列

  • 阻塞
    • 写入:如果队列中数据满了,就得阻塞等待
    • 读取:如果队列中无数据,就得阻塞等待
  • 队列
    • 队列遵循FIFO规则
BlockingQueue族谱

BlockingQueue

四种API(四种方法)

方式 抛出异常 不抛异常,正常返回值 阻塞等待 超时等待
添加 add offer put offer(E e, long timeout, TimeUnit unit)
移除 remove poll take E poll(long timeout, TimeUnit unit)
拿队首元素 element peek -- --
public class Test1 {
    public static void main(String[] args) throws InterruptedException {
//        f1();
        f2();
//        f3();
//        f4();
    }

    /**
     *  当存不进或是取不出来会抛出异常
     */
    public static void f1(){
        BlockingQueue queue = new ArrayBlockingQueue<>(3);//需要指定大小
        System.out.println("-------------存---------------");
        System.out.println(queue.add("a"));
        System.out.println(queue.add("b"));
        System.out.println(queue.add("c"));
        //拿到对首元素 对首没有元素抛出异常 java.util.NoSuchElementException
        System.out.println(queue.element());
        //java.lang.IllegalStateException: Queue full
        System.out.println(queue.add("d"));
        System.out.println("-------------取---------------");
        System.out.println(queue.remove());
        System.out.println(queue.remove());
        System.out.println(queue.remove());
        //java.util.NoSuchElementException
//        System.out.println(queue.remove());
    }

    /**
     *  当存不进不会抛出异常 返回false
     *   取不出来不会抛出异常 返回null
     */
    public static void f2(){
        BlockingQueue queue = new ArrayBlockingQueue<>(3);//需要指定大小
        System.out.println("-------------存---------------");
        System.out.println(queue.offer("a"));
        System.out.println(queue.offer("b"));
        System.out.println(queue.offer("c"));
        System.out.println(queue.offer("d"));//false
        //对首有元素取出 没有为null
        System.out.println(queue.peek());
        System.out.println("-------------取---------------");
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());
        System.out.println(queue.poll());//null
    }

    /**
     *  当存不进或取不出不会抛出异常
     *  会一直阻塞等待 程序就死了
     */
    public static void f3() throws InterruptedException {
        BlockingQueue queue = new ArrayBlockingQueue<>(3);//需要指定大小
        System.out.println("-------------存---------------");
        queue.put("a");
        queue.put("b");
        queue.put("c");
//        queue.put("d");
        System.out.println("-------------取---------------");
        System.out.println(queue.take());
        System.out.println(queue.take());
        System.out.println(queue.take());
//        System.out.println(queue.take());
    }

    /**
     *  当存不进不会抛出异常 会进行阻塞等待 等待时间自己设置 等待不到就返回false
     *   取不出来不会抛出异常 会进行阻塞等待 等待时间自己设置 等待不到就返回null
     */
    public static void f4() throws InterruptedException {
        BlockingQueue queue = new ArrayBlockingQueue<>(3);//需要指定大小
        System.out.println("-------------存---------------");
        System.out.println(queue.offer("a", 2, TimeUnit.SECONDS));
        System.out.println(queue.offer("b", 2, TimeUnit.SECONDS));
        System.out.println(queue.offer("c", 2, TimeUnit.SECONDS));
        System.out.println(queue.offer("d", 2, TimeUnit.SECONDS));//false
        System.out.println("-------------取---------------");
        System.out.println(queue.poll(2, TimeUnit.SECONDS));
        System.out.println(queue.poll(2, TimeUnit.SECONDS));
        System.out.println(queue.poll(2, TimeUnit.SECONDS));
        System.out.println(queue.poll(2, TimeUnit.SECONDS));//null
    }
}

SynchronousQueue同步队列

同步队列 没有容量,也可以视为容量为1的队列;
进去一个元素,必须等待取出来之后,才能再往里面放入一个元素;
put方法 和 take方法;
Synchronized 和 其他的BlockingQueue 不一样 它不存储元素;
put了一个元素,就必须从里面先take出来,否则不能再put进去值!
并且SynchronousQueue 的take是使用了lock锁保证线程安全的。

/**
 * 同步队列
 */
public class SynchronousQueueDemo {
    public static void main(String[] args) {
        BlockingQueue<String> synchronousQueue = new SynchronousQueue<>();
        //使用两个进程
        // 一个进程 放进去
        // 一个进程 拿出来
        new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName()+" Put 1");
                synchronousQueue.put("1");
                System.out.println(Thread.currentThread().getName()+" Put 2");
                synchronousQueue.put("2");
                System.out.println(Thread.currentThread().getName()+" Put 3");
                synchronousQueue.put("3");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"T1").start();

        new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName()+" Take "+synchronousQueue.take());
//                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+" Take "+synchronousQueue.take());
//                TimeUnit.SECONDS.sleep(3);
                System.out.println(Thread.currentThread().getName()+" Take "+synchronousQueue.take());

            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        },"T2").start();
    }
}

posted @ 2022-05-11 17:34  九月!!  阅读(32)  评论(0)    收藏  举报