JUC包下并发容器

集合

CopyOnWriteArrayList

内部实现为ReentrantLock作为锁实现操作互斥
Object[] 来存储数据 volatile修饰 保证可见性
对数组进行元素变化时,通过复制一个新的数组实现 开销比较大
该类的迭代器实现为 对原数组的快照进行操作 只能进行元素查询操作 不能进行元素修改操作

实现了List接口,作为列表使用。
实现了RandomAccess接口,支持快速随机索引查找。
public class CopyOnWriteArrayList
    implements List, RandomAccess, Cloneable, java.io.Serializable {

	// 持有一个默认的非公平的互斥锁 来实现操作的线程安全
    final transient ReentrantLock lock = new ReentrantLock();

	// 使用数组存储数据,支持根据下标快速定位元素
    private transient volatile Object[] array;

// 添加元素源码分析 
public boolean add(E e) {
        final ReentrantLock lock = this.lock;
        // 先获取锁
        lock.lock();
        
        try {
            Object[] elements = getArray();
            int len = elements.length;
            // 复制一个新的数组 新数组长度为当前数组长度+1
            Object[] newElements = Arrays.copyOf(elements, len + 1);
            newElements[len] = e;
            setArray(newElements);
            return true;
        } finally {
                // 释放锁
            lock.unlock();
        }
    }

public Iterator iterator() {
        return new COWIterator(getArray(), 0);
    }
// 迭代器
static final class COWIterator implements ListIterator {
		// 通过持有原数组的快照来实现迭代器
        private final Object[] snapshot;
        // 迭代器当前指向元素的下标
        private int cursor;
        // 当前小于快照最大则存在下一个
        public boolean hasNext() {
            return cursor < snapshot.length;
        }

        public boolean hasPrevious() {
            return cursor > 0;
        }

        @SuppressWarnings("unchecked")
        public E next() {
            if (! hasNext())
                throw new NoSuchElementException();
            return (E) snapshot[cursor++];
        }

        @SuppressWarnings("unchecked")
        public E previous() {
            if (! hasPrevious())
                throw new NoSuchElementException();
            return (E) snapshot[--cursor];
        }
        public int nextIndex() {
            return cursor;
        }
        public int previousIndex() {
            return cursor-1;
        }
		// 不支持添加 删除元素等可变操作
        public void remove() {
            throw new UnsupportedOperationException();
        }
        public void set(E e) {
            throw new UnsupportedOperationException();
        }
        public void add(E e) {
            throw new UnsupportedOperationException();
        }

CopyOnWriteArraySet

内部实现仅仅是将CopyOnWriteArrayList再次包装一次 通过CopyOnWriteArrayList.addIfAbsent(E e)方法来保证不存在重复元素

// 继承了AbstractSet 说明是集合
public class CopyOnWriteArraySet extends AbstractSet
        implements java.io.Serializable {
        // 持有CopyOnWriteArrayList对象 说明该集合实现只是包装了一下CopyOnWriteArrayList类
        private final CopyOnWriteArrayList al;

阻塞队列

ArrayBlockingQueue

有界的阻塞队列
存储数据的数据结构为有界数组 长度在创建时指定
多线程安全通过互斥锁ReentrantLock来保证
等待通知条件notEmpty notFull来实现线程的阻塞和唤醒
通过两个变量putIndex takeIndex表示下次对应的put和take操作位置 即表示首尾位置 takeIndex表示首 putIndex表示尾

该阻塞队列读和写锁未分开 , 因为数组是固定的,只能头部出队 尾部入队,根据putIndex和takeIndex能够直接定位到位置,性能很高不需要锁分离。

/** The queued items */
    final Object[] items;

    /** items index for next take, poll, peek or remove */
    int takeIndex;

    /** items index for next put, offer, or add */
    int putIndex;

    /** Number of elements in the queue */
    int count;

    /*
     * Concurrency control uses the classic two-condition algorithm
     * found in any textbook.
     */

    /** Main lock guarding all access */
    final ReentrantLock lock;

    /** Condition for waiting takes */
    private final Condition notEmpty;

    /** Condition for waiting puts */
    private final Condition notFull;

LinkedBlockingQueue

有界的阻塞队列 默认大小为Integer.MAX_VALUE
存储元素的数据结构为单链表 每个节点指向其下一个节点位置
多线程安全通过两个互斥锁来保证,takeLock putLock
等待通知条件notEmpty notFull来实现线程的阻塞和唤醒
头结点head和尾节点tail表示首尾位置 头结点不保存元素

读写锁分离的 因为链表操作 元素需要包装成对应的节点Node 存在性能开销。

/** The capacity bound, or Integer.MAX_VALUE if none */
    private final int capacity;

    /** Current number of elements */
    private final AtomicInteger count = new AtomicInteger();

    /**
     * Head of linked list.
     * Invariant: head.item == null
     */
    transient Node head;

    /**
     * Tail of linked list.
     * Invariant: last.next == null
     */
    private transient Node last;

    /** Lock held by take, poll, etc */
    private final ReentrantLock takeLock = new ReentrantLock();

    /** Wait queue for waiting takes */
    private final Condition notEmpty = takeLock.newCondition();

    /** Lock held by put, offer, etc */
    private final ReentrantLock putLock = new ReentrantLock();

    /** Wait queue for waiting puts */
    private final Condition notFull = putLock.newCondition();

你可能感兴趣的:(juc)