LinkedBlockingQueue

LinkedBlockingQueue 是阻塞式的无界队列

构造函数,初始化capacity为int最大值,创建头尾节点
	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);
    }
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    计算当前还能容纳多少元素,其中capacity是容量上限,count是原子整形,代表当前元素数量
    public int remainingCapacity() {
     
        return capacity - count.get();
    }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 插入元素,阻塞等待,直到插入成功
 public void put(E e) throws InterruptedException {
     
        if (e == null) throw new NullPointerException();
        final int c;
        包装数据为node节点
        final Node<E> node = new Node<E>(e);
        final ReentrantLock putLock = this.putLock;
        final AtomicInteger count = this.count;
        加锁
        putLock.lockInterruptibly();
        try {
     
        	容器满了,阻塞等待。
            while (count.get() == capacity) {
     
                notFull.await();
            }
            容器还有空间,插入数据,插入到链表尾部
            enqueue(node);
            c = count.getAndIncrement();
            如果还有剩余空间,唤醒阻塞在插入数据上的线程,c+1是因为原子自增,返回的是旧值
            if (c + 1 < capacity)
                notFull.signal();
        } finally {
     
            putLock.unlock();
        }
        c==0,可能是容器中的元素被获取完,唤醒可能阻塞的获取线程
        if (c == 0)
            signalNotEmpty();
    }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    插入元素,非阻塞式,
    public boolean offer(E e) {
     
        if (e == null) throw new NullPointerException();
        final AtomicInteger count = this.count;
        如果容器已经满了,直接返回false,不再阻塞
        if (count.get() == capacity)
            return false;
        final int c;
        final Node<E> node = new Node<E>(e);
        final ReentrantLock putLock = this.putLock;
        putLock.lock();
        try {
     
            if (count.get() == capacity)
                return false;
            enqueue(node);
            c = count.getAndIncrement();
            if (c + 1 < capacity)
                notFull.signal();
        } finally {
     
            putLock.unlock();
        }
        if (c == 0)
            signalNotEmpty();
        return true;
    }
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   获取元素,阻塞等待,直到获取成功
   public E take() throws InterruptedException {
     
        final E x;
        final int c;
        final AtomicInteger count = this.count;
        final ReentrantLock takeLock = this.takeLock;
        takeLock.lockInterruptibly();
        try {
     
        容器为空,阻塞等待
            while (count.get() == 0) {
     
                notEmpty.await();
            }
            队首元素出队
            x = dequeue();
            当前元素数量-1
            c = count.getAndDecrement();
            容器中还有元素,需要唤醒其他阻塞的获取线程
            if (c > 1)
                notEmpty.signal();
        } finally {
     
            takeLock.unlock();
        }
        如果容器之前满了,唤醒可能阻塞的 插入线程
        if (c == capacity)
            signalNotFull();
        return x;
    }   
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    获取元素,非阻塞
        public E poll() {
     
        final AtomicInteger count = this.count;
        如果容器为空,直接返回null
        if (count.get() == 0)
            return null;
        final E x;
        final int c;
        final ReentrantLock takeLock = this.takeLock;
        takeLock.lock();
        try {
     
            容器为空,直接返回null
            if (count.get() == 0)
                return null;
            容器不为空,队首元素出列
            x = dequeue();
            c = count.getAndDecrement();
            容器中还有元素,唤醒其他阻塞获取的线程
            if (c > 1)
                notEmpty.signal();
        } finally {
     
            takeLock.unlock();
        }
        如果容器之前是满的,唤醒阻塞的插入线程
        if (c == capacity)
            signalNotFull();
        return x;
    } 
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
   		获取队首元素,但是不删除该元素
        public E peek() {
     
        final AtomicInteger count = this.count;
        容器为空,直接返回null
        if (count.get() == 0)
            return null;
        final ReentrantLock takeLock = this.takeLock;
        takeLock.lock();
        try {
     
            return (count.get() > 0) ? head.next.item : null;
        } finally {
     
            takeLock.unlock();
        }
    }

你可能感兴趣的:(java集合)