自己动手实现BlockingQueue

    Java的java.util.concurrent.*包下有许多在并发场景下使用的集合,ArrayBlockingQueue是其中之一,它是一个循环队列,这个队列的特别之处在于take方法与put方法,分别对应队列的元素出列和元素入列操作,当队列为空时,take会使得线程进入等待状态,直到队列不为空,有元素能够出列才会继续执行;同理,当队列满时,put方法也会使得线程进入等待状态。

    实际上这是一个生产者-消费者模型,按照理解, 自己也试着实现了一个,代码如下

/**
 * Created by YotWei on 2018/7/1.
 */
public class BlockingQueue<E> {

    /**
     * 有界队列内部固定长度,因此可以用数组实现
     */
    private Object[] elements;

    /**
     * 队列的头和尾下标
     */
    private int head = 0, tail = 0;

    /**
     * 队列目前的长度
     */
    private int size;

    private ReentrantLock lock = new ReentrantLock();

    private Condition notEmpty = lock.newCondition();

    private Condition notFull = lock.newCondition();

    public BlockingQueue(int capacity) {
        this.elements = new Object[capacity];
    }

    public void put(E e) {
        lock.lock();
        try {
            while (size == elements.length)
                notFull.await();
            elements[tail] = e;
            if (++tail == elements.length) {
                tail = 0;
            }
            size++;
            notEmpty.signal();

        } catch (InterruptedException ex) {
            ex.printStackTrace();
        } finally {
            lock.unlock();
        }
    }

    public E take() {
        lock.lock();
        E e = null;
        try {
            while (size == 0) {
                notEmpty.await();
            }
            e = (E) elements[head];
            elements[head] = null;
            if (++head == elements.length)
                head = 0;
            size--;
            notFull.signal();

        } catch (InterruptedException ex) {
            ex.printStackTrace();
        } finally {
            lock.unlock();
        }
        return e;
    }

    public int size() {
        lock.lock();
        try {
            return size;
        } finally {
            lock.unlock();
        }
    }
}

    实际上ArrayBlockingQueue还包含许多其它方法,这两个是最核心的。

你可能感兴趣的:(Java,集合容器,多线程,队列,数据结构,并发控制)