JUC编程(六)-阻塞队列BlockingQueue

八.阻塞队列

BlockingQueue是继承自Queue的接口,支持在检索元素时等待队列变为非空的操作,并且在存储元素时等待队列中的空间变得可用。(可以用于生产者消费者场景)

实现类有:ArrayBlockingQueue,DelayQueue,LinkedBlockingDeque,LinkedBlockingQueue,LinkedTransferQueue,PriorityBlockingQueue,SynchronousQueue 

提供以下四种处理方法:

方式 抛出异常 不抛出异常,有返回值 阻塞 阻塞等待
添加 boolean add(E e) boolean offer(E e) void put(E e)  boolean offer(E e, long timeout, TimeUnit unit)
移除 E remove() E poll() E take() E poll(long timeout, TimeUnit unit) 
检测队首 E element() E peek() / /

ArrayBlockingQueue:

public class BlockQueue {
    public static void main(String[] args) {
        Queue queue = new Queue();
//        try {
//            queue.test3();
//        } catch (InterruptedException e) {
//            e.printStackTrace();
//        }
        try {
            queue.test4();
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}

class Queue{

    public void test1(){
        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(3);
        System.out.println(arrayBlockingQueue.add("1"));
        // 添加成功返回true
        System.out.println(arrayBlockingQueue.add("2"));
        System.out.println(arrayBlockingQueue.add("3"));
        // System.out.println(arrayBlockingQueue.add("4"));
        // 队列已满会抛出异常
        System.out.println("---");
        System.out.println(arrayBlockingQueue.remove());
        System.out.println(arrayBlockingQueue.remove());
        System.out.println(arrayBlockingQueue.remove());
        // System.out.println(arrayBlockingQueue.remove());
        // 队列为空抛出异常
    }

    public void test2(){
        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(3);
        System.out.println(arrayBlockingQueue.offer("1"));
        // 添加成功返回true
        System.out.println(arrayBlockingQueue.offer("2"));
        System.out.println(arrayBlockingQueue.offer("3"));
        System.out.println(arrayBlockingQueue.offer("4"));
        // 队列已满会返回false,不抛出异常
        System.out.println("---");
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        // 队列为空时返回null,不抛出异常
    }

    public void test3() throws InterruptedException {
        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(3);
        arrayBlockingQueue.put("1");
        // 没有返回值
        arrayBlockingQueue.put("2");
        arrayBlockingQueue.put("3");
        // arrayBlockingQueue.put("4");
        // 添加时如果队列已满会处于阻塞状态,直到队列有新的空间。
        System.out.println(arrayBlockingQueue.take());
        System.out.println(arrayBlockingQueue.take());
        System.out.println(arrayBlockingQueue.take());
        // System.out.println(arrayBlockingQueue.take());
        // 队列为空时,如果仍要取出数据,会处于等待状态
    }

    public void test4() throws InterruptedException {
        ArrayBlockingQueue arrayBlockingQueue = new ArrayBlockingQueue(3);
        System.out.println(arrayBlockingQueue.offer("1"));
        // 添加成功返回true
        System.out.println(arrayBlockingQueue.offer("2"));
        System.out.println(arrayBlockingQueue.offer("3"));
        // System.out.println(arrayBlockingQueue.offer("4"));
        // 添加失败返回false
        System.out.println(arrayBlockingQueue.offer("5",2,TimeUnit.SECONDS));
        // 可以设置等待时间
        System.out.println("---");
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll());
        System.out.println(arrayBlockingQueue.poll(2,TimeUnit.SECONDS));
        // 设置等待时间
    }
}

SynchronousQueue:

同步队列没有任何内部容量。 当put()一个元素后,必须等待take()之后才能再put()一个元素。

public class SyncQueue {
    public static void main(String[] args) {
        SynchronousQueue synchronousQueue = new SynchronousQueue();
        new Thread(()->{
            try {
                System.out.println(Thread.currentThread().getName()+" put:a");
                synchronousQueue.put("a");
                System.out.println(Thread.currentThread().getName()+" put:b");
                synchronousQueue.put("b");
                System.out.println(Thread.currentThread().getName()+" put:c");
                synchronousQueue.put("c");
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
        new Thread(()->{
            try {
                TimeUnit.SECONDS.sleep(2);
                System.out.println(Thread.currentThread().getName()+" get:"+synchronousQueue.take());
                TimeUnit.SECONDS.sleep(2);
                System.out.println(Thread.currentThread().getName()+" get:"+synchronousQueue.take());
                TimeUnit.SECONDS.sleep(2);
                System.out.println(Thread.currentThread().getName()+" get:"+synchronousQueue.take());
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }).start();
    }
}
运行结果
Thread-0 put:a
Thread-1 get:a
Thread-0 put:b
Thread-1 get:b
Thread-0 put:c
Thread-1 get:c
posted @ 2021-10-10 21:04  酥炸小黄瓜  阅读(49)  评论(0)    收藏  举报