ArrayBlockingQueue源码分析

    xiaoxiao2026-01-04  8

    ArrayBlockingQueue是一个有界的阻塞队列,底层维护的是一个数组。遵循先进先出FIFO,从尾部插入,从头部取出。如果队列已满,插入操作将阻塞,如果队列是空的,从队列里面取出元素也会阻塞。

    构造方法

    /* * fair 当多线程同时访问时,采用公平锁,还是非公平锁,默认 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(); }

    put添加元素:如果队列已满将阻塞

    public void put(E e) throws InterruptedException { checkNotNull(e); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { // 如果队列已满,插入操作将阻塞 while (count == items.length) notFull.await(); enqueue(e); } finally { lock.unlock(); } }

    add添加元素:如果队列已满将抛出异常

    public boolean add(E e) { return super.add(e); }

    offer添加元素:如果队列已满直接返回false, 不会抛出异常

    public boolean offer(E e) { checkNotNull(e); final ReentrantLock lock = this.lock; lock.lock(); try { //如果队列已满直接返回false if (count == items.length) return false; else { enqueue(e); return true; } } finally { lock.unlock(); } }

    offer添加元素:如果队列已满将先等待给定的时间间隔,如果在等待了给定的时间间隔之后还是满的,则返回false, 不会抛出异常

    public boolean offer(E e, long timeout, TimeUnit unit) throws InterruptedException { checkNotNull(e); long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { // 如果队列已满将先等待给定的时间间隔 while (count == items.length) { if (nanos <= 0) return false; nanos = notFull.awaitNanos(nanos); } enqueue(e); return true; } finally { lock.unlock(); } }

    take取出对应位置的元素,并将该位置的值设置为null, 如果队列为空,取出元素操作将阻塞

    public E take() throws InterruptedException { final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { //如果队列为空,取出元素操作将阻塞 while (count == 0) notEmpty.await(); return dequeue(); } finally { lock.unlock(); } }

    poll取出元素,并将该位置的值设置为null, 如果队列为空,立刻直接返回null

    public E poll() { final ReentrantLock lock = this.lock; lock.lock(); try { return (count == 0) ? null : dequeue(); } finally { lock.unlock(); } }

    poll取出元素,并将该位置的值设置为null, 如果队列为空,将先等待给定的时间间隔,如果在等待了给定的时间间隔之后还是空的,则返回null

    public E poll(long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { while (count == 0) { if (nanos <= 0) return null; nanos = notEmpty.awaitNanos(nanos); } return dequeue(); } finally { lock.unlock(); } }

    peek取出当前位置的元素,不会将其设置为null 与take不同,如果队列为空将返回null

    public E peek() { final ReentrantLock lock = this.lock; lock.lock(); try { return itemAt(takeIndex); // null when queue is empty } finally { lock.unlock(); } }

    toArray转换成数组

    public Object[] toArray() { Object[] a; final ReentrantLock lock = this.lock; lock.lock(); try { final int count = this.count; a = new Object[count]; int n = items.length - takeIndex; if (count <= n)// 说明putIndex一定在takeIndex与items.length之间 System.arraycopy(items, takeIndex, a, 0, count); else { System.arraycopy(items, takeIndex, a, 0, n); System.arraycopy(items, 0, a, n, count - n); } } finally { lock.unlock(); } return a; } 相关资源:python入门教程(PDF版)
    最新回复(0)