美文网首页
29-BlockingQueue

29-BlockingQueue

作者: 鹏程1995 | 来源:发表于2020-02-04 17:09 被阅读0次

类介绍

类定位

首先BlockingQueue直白的翻译过来就是阻塞队列,很容易联想到这是个和并发编程有关系的队列。最直白想象到的是在学操作系统的生产者——消费者和死锁相关的问题。

类继承关系分析

BlockingQueue继承于Queue。所以大概的情况如下所示:

1.png

因为比较懒,所以直接从idea中截图了。

类使用场景

这个类的主要使用场景就是多线程情况下的队列处理了。比如消息队列等等。这里放一个示例代码,是直接从jdk注解中复制出来的,代码思路是多个线程往里放东西取东西。

class Producer implements Runnable {
    private final BlockingQueue queue;

    Producer(BlockingQueue q) {
        queue = q;
    }

    public void run() {
        try {
            while (true) {
                queue.put(produce());
            }
        } catch (InterruptedException ex) { ...handle ...}
    }

    Object produce() { ...}
}

class Consumer implements Runnable {
    private final BlockingQueue queue;

    Consumer(BlockingQueue q) {
        queue = q;
    }

    public void run() {
        try {
            while (true) {
                consume(queue.take());
            }
        } catch (InterruptedException ex) { ...handle ...}
    }

    void consume(Object x) { ...}
}

class Setup {
    void main() {
        BlockingQueue q = new SomeQueueImplementation();
        Producer p = new Producer(q);
        Consumer c1 = new Consumer(q);
        Consumer c2 = new Consumer(q);
        new Thread(p).start();
        new Thread(c1).start();
        new Thread(c2).start();
    }
}}

类注意事项

注意事项如下:

  1. BlockingQueueQueue的一个子类,所以Queue的限制它都有,比如:

    1. 不一定是FIFO,可以自己设置排序顺序
    2. 不允许有null
  2. BlockingQueue是线程安全的,所以他的实现类不应该只把BlockingQueue自己的方法做成线程安全的,他继承的CollectionQueue的方法要全弄成线程安全的

源码解析

方法归类

我们将源码进行归类讲解,BlockingQueue对进队、出队、取队头三种方法有四种实现方式,我们列表如下:

Method Throws exception Special value Blocks Times out
Insert add(e) offer(e) put(e) offer(e, time, unit)
Remove remove() poll() take() poll(time, unit)
Examine element() peek() not applicable not applicable

注意:

  1. 我们将方法分成四类主要是依据当前队列的情况不允许立即入队/出队/取队头时,方法的操作。我们的不允许立即操作指的是队列满了不能入队或者队列空了不能出队,不是原子操作或者上锁引起的等待
  2. 四种方法,不能立即操作时会有不同的表现:比如抛异常、返回特殊值、阻塞等待、限时阻塞等待。

抛异常

boolean add(E e);

会抛异常

boolean remove(Object o);

E element();

返回特殊值

boolean offer(E e);

不合理入参也会抛异常

E poll();

E peek();

阻塞等待

void put(E e) throws InterruptedException;

入队列

E take() throws InterruptedException;

取队头

限时阻塞

boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException;

E poll(long timeout, TimeUnit unit) throws InterruptedException;

新功能的方法

int drainTo(Collection<? super E> c);

将此BlockingQueue中的元素剪切至目标Collection

注意:

  1. 此方法线程安全
  2. 如果方法执行时挂了,元素可能在this/C/no Where。所以挂了的话还是挺难搞的
  3. 在剪切过程中如果C出现了改变,会引起剪切失败
  4. 此方法效率比循环调用出队操作要高

int drainTo(Collection<? super E> c, int maxElements);

有个数量限制。

相关文章

  • 29-BlockingQueue

    类介绍 类定位 首先BlockingQueue直白的翻译过来就是阻塞队列,很容易联想到这是个和并发编程有关系的队列...

网友评论

      本文标题:29-BlockingQueue

      本文链接:https://www.haomeiwen.com/subject/wctdxhtx.html