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

相關文章
相關標籤/搜索