`
dieslrae
  • 浏览: 35393 次
  • 性别: Icon_minigender_1
  • 来自: 重庆
社区版块
存档分类
最新评论

读源码之:ArrayBlockingQueue

    博客分类:
  • Java
阅读更多
    ArrayBlockingQueue是concurrent包提供的一个线程安全的队列,由一个数组来保存队列元素.通过takeIndexputIndex来分别记录出队列和入队列的下标,以保证在出队列时不进行元素移动.

//在出队列或者入队列的时候对takeIndex或者putIndex进行累加,如果已经到了数组末尾就又从0开始,保证数组的循环使用.
final int inc(int i) {
        return (++i == items.length) ? 0 : i;
    }

//入队列操作
private void insert(E x) {
        items[putIndex] = x;
        putIndex = inc(putIndex);
        ++count;
        notEmpty.signal();//唤醒等待的出队线程
    }

//使用offer入队列,如果队列已满就立即返回false
public boolean offer(E e) {
        checkNotNull(e);
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            if (count == items.length)
                return false;
            else {
                insert(e);
                return true;
            }
        } finally {
            lock.unlock();
        }
    }

//使用put入队列的话,如果队列已满当前线程就等待然后释放锁,直到被notFull唤醒,再重新检查,直到成功插入队列
public void put(E e) throws InterruptedException {
        checkNotNull(e);
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (count == items.length)
                notFull.await();
            insert(e);
        } finally {
            lock.unlock();
        }
    }

//出队列操作
private E extract() {
        final Object[] items = this.items;
        E x = this.<E>cast(items[takeIndex]);
        items[takeIndex] = null;
        takeIndex = inc(takeIndex);
        --count;
        notFull.signal();//唤醒等待入队的线程
        return x;
    }

//poll出队是不需要等待的,如果当前队列是空就直接返回null
public E poll() {
        final ReentrantLock lock = this.lock;
        lock.lock();
        try {
            return (count == 0) ? null : extract();
        } finally {
            lock.unlock();
        }
    }

//take就跟put一样,如果队列是空的就等待直到被notEmpty唤醒
public E take() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            while (count == 0)
                notEmpty.await();
            return extract();
        } finally {
            lock.unlock();
        }
    }


最后需要注意的就是带超时唤醒的是offerpoll而不是put和take
0
0
分享到:
评论

相关推荐

    java多线程设计模式详解(PDF及源码)

    - **CopyOnWriteArrayList/CopyOnWriteArraySet**:适用于读多写少的情况,读操作无需加锁,写操作则复制整个集合。 7. **源码分析** - PDF文档和源码结合可以帮助读者深入理解多线程设计模式的实际应用,通过...

    Java多线程programmingShiZhanZhiNan(呵心篇).源码

    Java多线程编程实战指南(呵心篇)是一份深入探讨Java并发编程的资源,它提供了丰富的源码示例来帮助开发者理解并掌握多线程技术。在这个领域,Java提供了强大的支持,使得开发者能够构建高性能、高并发的应用程序。...

    Java多线程设计模式(附带书中源码)

    Java中可以使用`BlockingQueue`接口及其实现(如`ArrayBlockingQueue`)来实现此模式,通过`put()`和`take()`方法控制生产和消费的同步。 2. **线程池模式**:Java中的`ExecutorService`和`ThreadPoolExecutor`是...

    JavaInterview:最开源的Java技术知识点,以及Java源码分析。为开源贡献自己的一份力

    ArrayBlockingQueue LinkedBlockingQueue LinkedBlockingDeque :scroll: 主要介绍LeetCode上面的算法译文,以及面试过程中遇到的实际编码问题总结。 :locked: :file_folder: :laptop: :globe_showing_Asia-...

    多线程面试题及处理方案和详解

    - **ArrayBlockingQueue**:基于数组的有界阻塞队列。 - **LinkedBlockingQueue**:基于链表的阻塞队列,可以设置容量也可以不限制。 以上总结了多线程面试中的常见问题及解决方案,包括但不限于`synchronized`...

    一线大厂Java多线程面试120题.pdf

    Java多线程是Java开发中的核心技能之一,尤其在面试中,对于一线大厂的面试者来说,深入理解和掌握多线程的相关知识点至关重要。以下是一些关键的Java多线程面试知识点: 1. **自旋锁**:自旋锁是一种等待机制,当...

    java多线程设计模式详解

    关键在于同步和阻塞机制,Java中可以使用BlockingQueue接口来实现,例如ArrayBlockingQueue。 2. **单例模式**:在多线程环境中,确保一个类只有一个实例非常重要,以避免资源竞争和不一致状态。Java中可以使用双重...

    java并发集合

    它们在添加或删除元素时会创建一个新的底层数组,然后将原有数组的引用更改为新数组,这样在读取时不会阻塞写操作,适用于读多写少的场景。 3. **BlockingQueue**: 这是一种线程安全的队列,主要用于生产者-消费者...

    Java Concurrency In Practice Learning Note

    本书《Java Concurrency In Practice》是Java并发编程的经典之作,由Brian Goetz、Tim Peierls、Joshua Bloch、David Holmes和Doug Lea等多位专家共同撰写,为开发者提供了深入理解并有效利用Java并发工具的全面指南...

    Java 高并发五:JDK并发包1详细介绍

    2. 并发容器及典型源码分析并发容器是Java并发编程中不可或缺的一部分,它们提供了线程安全的数据结构,可以高效地处理多线程环境下的数据共享。以下是一些重要的并发容器: 2.1 ConcurrentHashMap并发哈希映射表,...

Global site tag (gtag.js) - Google Analytics