专栏首页IT云清LinkedBlockingQueue和ArrayBlockingQueue对比

LinkedBlockingQueue和ArrayBlockingQueue对比

对比一下LinkedBlockingQueue和ArrayBlockingQueue的区别。

1.底层数据结构不同

LinkedBlockingQueue底层是单向链表,只有一个后继指针

    /**
     * Linked list node class
     */
    static class Node<E> {
        E item;

        /**
         * One of:
         * - the real successor Node
         * - this Node, meaning the successor is head.next
         * - null, meaning there is no successor (this is the last node)
         */
        Node<E> next;

        Node(E x) { item = x; }
    }

ArrayBlockingQueue底层是数组

    /** The queued items */
    final Object[] items;

2.队列大小

LinkedBlockingQueue的构造函数,可以显示指定队列大小,也可以不指定,不指定大小事,默认是Integer.MAX_VALUE,可以观察他的三个构造函数:

    public LinkedBlockingQueue() {
        this(Integer.MAX_VALUE);
    }

    public LinkedBlockingQueue(int capacity) {
        if (capacity <= 0) throw new IllegalArgumentException();
        this.capacity = capacity;
        last = head = new Node<E>(null);
    }

    public LinkedBlockingQueue(Collection<? extends E> c) {
        this(Integer.MAX_VALUE);
        final ReentrantLock putLock = this.putLock;
        putLock.lock(); // Never contended, but necessary for visibility
        try {
            int n = 0;
            for (E e : c) {
                if (e == null)
                    throw new NullPointerException();
                if (n == capacity)
                    throw new IllegalStateException("Queue full");
                enqueue(new Node<E>(e));
                ++n;
            }
            count.set(n);
        } finally {
            putLock.unlock();
        }
    }

ArrayBlockingQueue的构造函数中,必须显示指定队列大小:

    public ArrayBlockingQueue(int capacity) {
        this(capacity, false);
    }

    public ArrayBlockingQueue(int capacity, boolean fair) {
        if (capacity <= 0)
            throw new IllegalArgumentException();
        this.items = new Object[capacity];
        lock = new ReentrantLock(fair);
        notEmpty = lock.newCondition();
        notFull =  lock.newCondition();
    }

    public ArrayBlockingQueue(int capacity, boolean fair,
                              Collection<? extends E> c) {
        this(capacity, fair);

        final ReentrantLock lock = this.lock;
        lock.lock(); // Lock only for visibility, not mutual exclusion
        try {
            int i = 0;
            try {
                for (E e : c) {
                    checkNotNull(e);
                    items[i++] = e;
                }
            } catch (ArrayIndexOutOfBoundsException ex) {
                throw new IllegalArgumentException();
            }
            count = i;
            putIndex = (i == capacity) ? 0 : i;
        } finally {
            lock.unlock();
        }
    }

3.使用的锁不同

LinkedBlockingQueue中,有两个锁,都是非公平锁:

    /** Lock held by take, poll, etc */
    private final ReentrantLock takeLock = new ReentrantLock();

    /** Lock held by put, offer, etc */
    private final ReentrantLock putLock = new ReentrantLock();

ArrayBlockingQueue中,只有一个锁,默认是个非公平锁,也可以显示指定为公平锁:

    /** Main lock guarding all access */
    final ReentrantLock lock;
    public ArrayBlockingQueue(int capacity) {
        this(capacity, false);//默认是非公平锁
    }

    public ArrayBlockingQueue(int capacity, boolean fair) {
        if (capacity <= 0)
            throw new IllegalArgumentException();
        this.items = new Object[capacity];
        lock = new ReentrantLock(fair);
        notEmpty = lock.newCondition();
        notFull =  lock.newCondition();
    }

    public ArrayBlockingQueue(int capacity, boolean fair,
                              Collection<? extends E> c) {
        this(capacity, fair);

        final ReentrantLock lock = this.lock;
        lock.lock(); // Lock only for visibility, not mutual exclusion
        try {
            int i = 0;
            try {
                for (E e : c) {
                    checkNotNull(e);
                    items[i++] = e;
                }
            } catch (ArrayIndexOutOfBoundsException ex) {
                throw new IllegalArgumentException();
            }
            count = i;
            putIndex = (i == capacity) ? 0 : i;
        } finally {
            lock.unlock();
        }
    }

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • redisson的MultiLock连锁

    Redis based distributed RedissonMultiLock object groups multiple RLock objects a...

    IT云清
  • kafka安装教程

    本文记录在linux环境下,安装kafka,并做简单测试,如果zookeeper没有安装,可参考zookeeper安装:

    IT云清
  • Docker---(5)Docker 部署SpringBoot web项目

    SpringBoot项目发布到服务器,是一件很简单的事情,但是发布到服务器上docker启动的tomcat容器中,有一些坑,需要注意。

    IT云清
  • 【JS】415- JS面向对象之 7 大基本原则

    如果我们在编写程序的时候,一类或者一个方法里面包含了太多方法,对于代码的可读性来说,无非是一场灾难,对于我们来说。所以为了解决这个问题,出现了单一职责。

    pingan8787
  • 如何解决NFV带来的新复杂性和网络盲点

    SDNLAB
  • 最基本的调试是NSLog及DEBUG预处理器宏

    在系统控制台显示日志信息运行应用程序时是最早调试机制之一,利用log你可以查看应用程序的运行记录,当程序运行完毕,你可以长时间查看。此外,您的应用程序运行期间,...

    君赏
  • Condition控制线程通信:java三个线程循环打印ABC

    private Lock lock = new ReentrantLock(); private Condition c1 = lock.newConditi...

    用户1215919
  • Flexbox在表单布局的应用

    上面是一个空表单。根据 HTML 标准,它是一个块级元素,默认将占据全部宽度,但是高度为0,因为没有任何内容。

    javascript.shop
  • Python网络爬虫进阶扩展(完)

    Python知识大全
  • 从Demo到光子芯片,Magic Leap是希望or“骗局”?

    镁客网

扫码关注云+社区

领取腾讯云代金券