java的concurrent包的存储类

java的concurrent包的存储类

        简略的翻看一下concurrent包,一部分是经过继承AbstractQueuedSynchronizer实现(ReentrantLock、CountDownLatch、semaphore等),一部分经过lock实现(CycliBarrier、atomic、blockingqueue、concurrentMap等)。抽象类AbstractQueuedSynchronizer又主要是经过一个自定义的Node的自定义队列来存储线程,而后经过unsafe类(native)来实现指令级别的compare and swap获取对内存中的共享区域控制权(也就是锁)。而后unpark、park操做线程的入队、出队(在Node上解释的使用一个FIFO的CLH对列来存放)。如今描述下concurrent中的集合和atomic。
html

一、atomic

        原子量:保证了CPU读、修改、写。可是不保证可见性,数据不知道是刷新到主存仍是缓存。包括了:AtomicBoolean、AtomicInteger、AtomicLong、AtomicReference、AtomicStamped、AtomicIntegerArray、AtomicLongArray、AtomicReferenceArray。
java

        atomic变量都是使用
算法

private volatile int value;

        做为存储量,而后利用本地方法:unsafe中的compareAndSwapInt()等方法来修改内存中的数据,从而达到原子操做的功能。数组

二、blockingQueue

        blockingQueue集合是concurrent最有用的工具集合之一。它运行线程从一边存放、一边读取。而且读为空、写满的状况都会阻塞。缓存

        这个接口主要有下面的方法
安全

        这个接口衍生出来了ArrayBlockingQueue、DelayQueue、LinkedBlockingQueue、PriorityBlockingQueue、SynchronouseQueue等集合。
并发

        其中最经常使用的的ArrayBlockQueueLinkedBlockingQueue是经过
高并发

//ArrayBlockingQueue
final Object[] items; 
final ReentrantLock lock;
private final Condition notEmpty;
private final Condition notFull;

//LinkedBlockingQueue   
static class Node<E>;    //链表节点
private final ReentrantLock takeLock = new ReentrantLock();
private final Condition notEmpty = takeLock.newCondition();
private final ReentrantLock putLock = new ReentrantLock();
private final Condition notFull = putLock.newCondition();

        实现的。也就是一个生产消费者模式。而且它们是线程安全、在高并发的状况下推荐使用,代替arrayList、linkedList。
工具

三、concurrentMap

        ConcurrentHashMap:使用的是“分段锁”。同时使用segment来存放数据,每个k都会更加hash算法,计算出不一样的segment。在segment里面使用lock来加锁,直接将一个打得map集合,分散成很小的map数组,减小了占用时间。atom

        concurrentHashMap的诞生用来在高并发的条件下代替hashTable(hashmap的synchronized版)。

        应用:

ConcurrentMap concurrentMap = new ConcurrentHashMap();
concurrentMap.put("key", "value");
Object value = concurrentMap.get("key");

        查看源码:经过实现一个静态嵌入内部类实现存储节点

static class Node<K,V> implements Map.Entry<K,V> {
        final int hash;    //key的hash值,用来快速定位查找的对象的位置
        final K key;        
        volatile V val;
        volatile Node<K,V> next;
}

        而且,在兑取对象时并不会把整个Map锁住(经过unsafe的getObjectVolatile()方法)。此外,向其写入对象的时候,也不会将全部的数据锁住。

        大概流程:concurrentHashMap会建立一个Node<K,V>[]出来存放Node<K,V>的链表地址。而后在存放、读取的时候经过神奇的unsafe指令(直接操做指令)来肯定key.hash表明的Node<K,V>的地址,而且锁住它。这样就不会锁住整个concurrentHashMap了。以下图


四、Jakob jenkow的博客

    concurent教程:http://tutorials.jenkov.com/java-util-concurrent/index.html

相关文章
相关标签/搜索