LinkedBlockingQueue是如何实现阻塞队列的

/**
     * Inserts the specified element at the tail of this queue, waiting if
     * necessary for space to become available.
     *
     * @throws InterruptedException {@inheritDoc}
     * @throws NullPointerException {@inheritDoc}
     */
    public void put(E e) throws InterruptedException {
        
        //如果为空  直接抛出异常
        if (e == null) throw new NullPointerException();    
        int c = -1;
         
        //把传入的值当作一个队列的新节点
        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 = 当前队列的没 ++ 之前的值
            c = count.getAndIncrement();
            //如果队列不满  唤醒一个 入队线程
            if (c + 1 < capacity)
                notFull.signal();
        } finally {
            //释放锁
            putLock.unlock();
        }
        
        //如果都列中只有1个值
        if (c == 0)
            //唤醒所有消费者线程
            signalNotEmpty();
    }
/**
     * 检索并删除此队列的头,如有必要,等待直到某个元素可用
     */
    public E take() throws InterruptedException {
        E x;
        int c = -1;
        //当前队列长度
        final AtomicInteger count = this.count;
        //出队锁
        final ReentrantLock takeLock = this.takeLock;
        //得到一个可被中断的锁
        takeLock.lockInterruptibly();
        try {
        	//如果当前队列 长度为0 则线程等待
            while (count.get() == 0) {
                notEmpty.await();
            }
            //弹出队列首个元素
            x = dequeue();
            //队列总数-1
            c = count.getAndDecrement();
            //如果队列大于1   唤醒一个  消费者线程
            if (c > 1)
                notEmpty.signal();
        } finally {
        	//释放锁
            takeLock.unlock();
        }
        //如果 队列只剩下1个  容量  通知所有生产者线程
        if (c == capacity)
            signalNotFull();
        return x;
    }
发布了11 篇原创文章 · 获赞 1 · 访问量 365

猜你喜欢

转载自blog.csdn.net/qq_37421368/article/details/83149823
今日推荐