`
zhuhui_zj
  • 浏览: 36640 次
  • 性别: Icon_minigender_1
  • 来自: 杭州
社区版块
存档分类
最新评论

并发容器分析(二)--ArrayBlockingQueue

阅读更多

一、简介

    BlockingQueue接口定义了一种阻塞的FIFO queue,每一个BlockingQueue都有一个容量,让容量满时往BlockingQueue中添加数据时会造成阻塞,当容量为空时取元素操作会阻塞。ArrayBlockingQueue是对BlockingQueue的一个数组实现,它使用一把全局的锁并行对queue的读写操作,同时使用两个Condition阻塞容量为空时的取操作和容量满时的写操作。

二、具体实现

    ArrayBlockingQueue底层定义如下:

 

public class ArrayBlockingQueue<E> extends AbstractQueue<E>
        implements BlockingQueue<E>, java.io.Serializable {

    // 使用循环数组来实现queue,初始时takeIndex和putIndex均为0
    private final E[] items;
    private transient int takeIndex;
    private transient int putIndex;
    private int count;

    // 用于并发的锁和条件
   private final ReentrantLock lock;
    private final Condition notEmpty;
    private final Condition notFull;

    /**
     * 循环数组
     * Circularly increment i.
     */
    final int inc(int i) {
        return (++i == items.length)? 0 : i;
    }

    public ArrayBlockingQueue(int capacity, boolean fair) {
        if (capacity <= 0)
            throw new IllegalArgumentException();
        this.items = (E[]) new Object[capacity];
        // 分配锁及该锁上的condition
        lock = new ReentrantLock(fair);
        notEmpty = lock.newCondition();
        notFull =  lock.newCondition();
    }

  ...
}

   ArrayBlockingQueue的取操作:

public class ArrayBlockingQueue<E> extends AbstractQueue<E>
        implements BlockingQueue<E>, java.io.Serializable {

    private E extract() {
        final E[] items = this.items;
        E x = items[takeIndex];
        items[takeIndex] = null;
        takeIndex = inc(takeIndex);
        --count;
       // 激发notFull条件
        notFull.signal();
        return x;
    }

     /**
        * condition的await的语义如下:
     * 与condition相关的锁以原子方式释放,并禁用该线程
     * 方法返回时,线程必须获得与该condition相关的锁
     */
    public E take() throws InterruptedException {
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            try {
            	  // 等待notEmpty的条件
                while (count == 0)
                    notEmpty.await();
            } catch (InterruptedException ie) {
                notEmpty.signal(); // propagate to non-interrupted thread
                throw ie;
            }
            E x = extract();
            return x;
        } finally {
            lock.unlock();
        }
    }

  ...
}

   ArrayBlockingQueue的写操作:

public class ArrayBlockingQueue<E> extends AbstractQueue<E>
        implements BlockingQueue<E>, java.io.Serializable {

    private void insert(E x) {
        items[putIndex] = x;
        putIndex = inc(putIndex);
        ++count;
        notEmpty.signal();
    }

    public void put(E o) throws InterruptedException {
        if (o == null) throw new NullPointerException();
        final E[] items = this.items;
        final ReentrantLock lock = this.lock;
        lock.lockInterruptibly();
        try {
            try {
            	  // 等待notFull条件
           while (count == items.length)
                    notFull.await();
            } catch (InterruptedException ie) {
                notFull.signal(); // propagate to non-interrupted thread
                throw ie;
            }
            insert(o);
        } finally {
            lock.unlock();
        }
    }

  ...
}

    注意:ArrayBlockingQueue在读写操作上都需要锁住整个容器,因此吞吐量与一般的实现是相似的,适合于实现“生产者消费者”模式。

 

分享到:
评论

相关推荐

    并发容器的原理,7大并发容器详解、及使用场景

    并发容器的出现解决了传统同步容器在性能上的不足,通过引入更先进的并发控制策略,如锁分段、CAS算法等,提升了程序的并发性和吞吐量。 首先,我们要理解什么是同步容器。Java 集合框架中的非线程安全容器,如 ...

    并发容器之ArrayBlockingQueue和LinkedBlockingQueue实现原理详解

    "并发容器之ArrayBlockingQueue和LinkedBlockingQueue实现原理详解" ArrayBlockingQueue和LinkedBlockingQueue是Java并发容器中两个常用的阻塞队列实现,分别基于数组和链表存储元素。它们都继承自AbstractQueue类...

    实战Java高并发程序设计第二版随书代码

    - **线程安全的集合类**:如Vector、HashTable、Collections.synchronizedXXX() 方法产生的同步容器,以及CopyOnWriteArrayList 和 CopyOnWriteArraySet 等并发容器。 - **ConcurrentHashMap**:Java并发编程的...

    Java从同步容器到并发容器的操作过程

    Java中的同步容器与并发容器是处理多线程环境下数据安全的重要工具。同步容器,如`Vector`和`HashTable`,通过在每个方法上添加`synchronized`关键字实现了线程安全,但这种方式存在性能瓶颈,因为每次操作都需要...

    【2018最新最详细】并发多线程教程

    20.并发容器之ArrayBlockingQueue和LinkedBlockingQueue实现原理详解 21.线程池ThreadPoolExecutor实现原理 22.线程池之ScheduledThreadPoolExecutor 23.FutureTask基本操作总结 24.Java中atomic包中的原子操作类...

    Java高并发经典文档-MOBI-可在电子书里查看

    2. **并发容器** - **并发集合**:包括线程安全的`Vector`、`Collections.synchronizedXXX`方法转换的同步集合,以及更高效的`ConcurrentHashMap`、`CopyOnWriteArrayList`等并发集合。 - **阻塞队列**:如`...

    计算机后端-Java-Java高并发从入门到面试教程-课程准备.zip

    - **线程安全容器**:如Vector、Collections.synchronizedXXX()方法创建的容器,以及ConcurrentHashMap、CopyOnWriteArrayList等高效并发容器的使用。 - **并发队列**:如ArrayBlockingQueue、LinkedBlockingQueue...

    JAVA并发容器代码随读1

    Java并发容器是Java多线程编程中的重要工具,它们提供了高效、线程安全的数据结构,使得在并发环境下处理数据变得更加简单。在`java.util.concurrent`包中,有四种主要的并发容器类型:队列(BlockingQueue)、Map...

    计算机后端-Java-Java高并发从入门到面试教程-发课程资料.zip

    3. **并发容器** - **并发集合**:如ConcurrentHashMap、CopyOnWriteArrayList等,了解它们的设计原理和使用场景。 - **阻塞队列BlockingQueue**:如ArrayBlockingQueue、LinkedBlockingQueue等,理解其在生产者-...

    计算机后端-Java-Java高并发从入门到面试教程-存思路.zip

    2. **并发容器** - **ArrayList vs LinkedList**:比较两者的性能差异,以及在并发环境下的适用性。 - **Vector与Collections.synchronizedList**:了解同步容器的局限性。 - **ConcurrentHashMap**:分析其线程...

    JAVA并发编程实践-构建执行程序块-学习笔记

    并发容器-并⾏是指在多线程环境下,使用并发容器来实现线程安全的容器。例如,ConcurrentHashMap、CopyOnWriteArrayList等都是并发容器-并⾏。 CopyOnWriteArrayList是指在多线程环境下,使用CopyOnWriteArrayList...

    java并发源码分析之实战编程

    在这个专题中,我们将围绕Java并发库、线程管理、锁机制、并发容器以及并发工具类等方面进行深入的源码分析。 首先,Java并发库(java.util.concurrent)是Java并发编程的核心,提供了多种高级并发结构,如Executor...

    java并发编程实战源码-JavaConcurrentProgramming:《Java并发编程实战》

    - **并发容器**:`BlockingQueue`接口及其实现,如`ArrayBlockingQueue`、`LinkedBlockingQueue`,常用于生产者-消费者模型。 4. **原子类** - `Atomic`系列类,如`AtomicInteger`、`AtomicLong`、`...

    JUC并发编程学习笔记(硅谷)

    3. **并发容器** - `ConcurrentHashMap`:线程安全的哈希表,理解其分段锁的设计和操作流程。 - `Atomic`类:如`AtomicInteger`,提供原子操作,用于在不使用锁的情况下实现线程安全。 - `BlockingQueue`:阻塞...

    并发编程实践,全面介绍基础知识、JVM同步原语、线程安全、低级并发工具、线程安全容器、高级线程协作工具、Executor部分等

    - **并发容器**:如ArrayList、HashMap的并发版本(CopyOnWriteArrayList、ConcurrentHashMap),设计为线程安全,但效率更高。 - **阻塞队列**:如ArrayBlockingQueue、LinkedBlockingQueue,提供生产者-消费者...

    实战Java高并发程序设计-12333.pdf

    2. **并发容器**:如`ConcurrentHashMap`、`BlockingQueue`(如`ArrayBlockingQueue`、`LinkedBlockingQueue`)等,这些容器在并发环境下提供高效且安全的数据共享机制。 3. **线程池**:`ExecutorService`和`...

    【面试资料】-(机构内训资料)Java并发编程面试题.zip

    5. **并发容器** - `BlockingQueue`阻塞队列:实现生产者消费者模型,如`ArrayBlockingQueue`、`LinkedBlockingQueue`等。 - `ConcurrentHashMap`并发哈希表:线程安全的哈希表,性能优于`synchronized`修饰的`...

    JAVA并发编程实践

    - 选择合适的并发容器; - 适时采用线程池。 ### 总结 《JAVA并发编程实践》一书深入浅出地介绍了Java并发编程的核心概念和技术细节,不仅适合Java开发新手入门,也适合有一定经验的开发者作为参考指南。通过本书...

    并发容器——BlockingQueue相关类

    在Java编程中,`BlockingQueue`是一个非常重要的并发容器,它是Java并发包`java.util.concurrent`中的核心组件。`BlockingQueue`实现了一种线程安全的数据结构,它能够有效地协调生产者和消费者的动作,实现高效的...

    14个Java并发容器,你用过几个?.docx

    以下是对标题和描述中提及的一些并发容器的详细解释: 1. **ConcurrentHashMap**: 是线程安全的HashMap实现,它在不同JVM版本中采用了不同的策略。在Java 7中,它使用分段锁,每个段是一个独立的HashMap,减少锁...

Global site tag (gtag.js) - Google Analytics