并发容器分析(五)--ConcurrentHashMap
来源:互联网 发布:录音整理软件 编辑:程序博客网 时间:2024/06/15 02:15
一、简介
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在读写操作上都需要锁住整个容器,因此吞吐量与一般的实现是相似的,适合于实现“生产者消费者”模式。
http://zhuhui-zj.iteye.com/blog/784192
- 并发容器分析(五)--ConcurrentHashMap
- jdk1.8并发容器:ConcurrentHashMap源码分析
- java并发容器ConcurrentHashMap源码分析
- Java并发编程札记-(五)JUC容器-03ConcurrentHashMap
- 并发容器之ConcurrentHashMap
- 并发容器ConcurrentHashMap
- 并发容器之ConcurrentHashMap
- Java并发编程:并发容器之ConcurrentHashMap(转载)
- Java并发编程:并发容器之ConcurrentHashMap(转载)
- JAVA并发编程:并发容器之ConcurrentHashMap(转载)
- Java并发编程:并发容器之ConcurrentHashMap(转载)
- Java并发编程:并发容器之ConcurrentHashMap(转载)
- 并发编程复习(七):并发类容器ConcurrentHashMap&CopyOnWrite
- Java并发编程(五)ConcurrentHashMap的实现原理和源码分析
- Java并发编程(五)ConcurrentHashMap的实现原理和源码分析
- java多线程-并发容器ConcurrentHashMap
- java并发容器ConcurrentHashMap学习心得
- 并发容器ConcurrentHashMap深度剖析
- java.nio.ByteBuffer 详解
- Android主平台用户和组的配置,文件为 android_filesystem_config.h
- Tomcat启动后加载两次web.xml的问题
- 一个浏览指定文件格式的 TreeView
- UDP与TCP协议
- 并发容器分析(五)--ConcurrentHashMap
- Android GPS (当前位置 & GPS信息更新)
- Tomcat内存溢出的三种情况及解决办法分析
- 关于matlab Error in ==> blkproc at 87的解决办法。
- android 通话记录去重查询方法
- C#取得页面URL信息(转自:http://kb.cnblogs.com/a/1508673/)
- Oracle rman备份和还原恢复数据库
- C#中Release和debug模式下调试跟踪程序的原则和方法(转)
- windows+putty+linux+emacs+cscope+auto-complete+ecb 将emacs配置为一个可以编程的IDE