讀書筆記之《Java併發編程的藝術》-併發編程容器和框架(重要)

讀書筆記部份內容來源書出版書,版權歸本書做者,若有錯誤,請指正。java

歡迎star、fork,讀書筆記系列會同步更新git

git
程序員

https://github.com/xuminwlt/j360-jdkgithub

module編程

j360-jdk-thread/me.j360.jdk.concurrent數組

本系列分4篇安全

一、讀書筆記之《Java併發編程的藝術》-併發編程基礎多線程

二、讀書筆記之《Java併發編程的藝術》-java中的鎖併發

三、讀書筆記之《Java併發編程的藝術》-併發編程容器和框架(重要)框架

四、讀書筆記之《Java併發編程的藝術》-線程池和Executor的子孫們

本書前三章分別爲

  1. 併發編程的挑戰,也就是併發編程的原因所在

  2. 底層的實現原理

  3. java內存模型

分別從cpu x86,x64以及內存模型等概念中描述java對併發編程的實現和控制,概念較爲底層和基礎,讀書筆記略過前三章直接從第四章應用實現及原理基礎開始。

章節

  1. 併發編程基礎

  2. java中的鎖

  3. 併發容器和框架(重點)

  4. 13個操做原子類

  5. java併發工具類

  6. 線程池

  7. Execurot框架

內容

本章節開始是我認爲的重點,這裏是日常開發中打交道最多的併發框架,在瞭解到併發編程的基礎已經實現原理後,日常不多去使用,而後做爲j2se5以後加入的併發框架,讓從事java開發的我們相比其餘語言的程序員幸福的多,這一切皆由於Doug Lea大師不潰餘力地爲java開發者提供了很是多的java併發容器和框架

3節:併發容器和框架

ConcurrentHashMap

使用的鎖分段技術,將數據一段一段地存儲,給一段配一把鎖

初始化

初始化方法經過initialCapacity、loadFactor、concurrencyLevel等幾個參數來初始化segment數組、段偏移量segmentShift、段掩碼segmentMask和每一個segment裏的HashEntity數組來實現的

操做

get操做,get操做的高效之處在於整個get過程不須要加鎖,除非讀到的值是空纔會加鎖重讀。

public V get(Object key){
    int hash = hash(key.hashCode));
    return segmentFor(hash).get(key,hash);
}

put操做,須要對共享變量進行寫入操做,爲了線程安全

ConcurrentLinkedQueue

基於連接節點的無界線程安全隊列,採用先進先出FIFO的規則對節點進行排序

Java中的阻塞隊列

jdk7提供了7個阻塞隊列

ArrayBlockingQueue

LinkedBlockingQueue

PriorityBlockingQueue

DelayQueue

SynchronusQueue

LinkedTransferQueue

LinkedBlockingDeque

Fork/join框架

jdk7提供的用於並行執行任務的框架

框架設計

步驟1:分隔任務

步驟2:執行任務併合並結果

Fork.join使用兩個類來完成以上兩件事情

一、ForkJoinTask

    RecursiveAction:用於沒有返回結果的任務

    RecursiveTask:用於有返回結果的任務

二、ForkJoinPool

    ForkJonkTask須要經過ForkJoinPool來執行

使用Fork/join框架:計算1+2+3+4的結果

public class CountTask extends RecursiveTask<Integer> {

    private static final int THRESHOLD = 2; //閾值
    private int start;
    private int end;

    public CountTask(int start,int end){
        this.start = start;
        this.end = end;
    }
    @Override
    protected Integer compute() {
        int sum = 0;
        boolean canCompute = (end-start) <= THRESHOLD;
        if(canCompute){
            for(int i=start;i<=end;i++){
                sum += i;
            }
        }else{
            int middle = (start + end )/2;
            CountTask leftTask = new CountTask(start,middle);
            CountTask rightTask = new CountTask(middle,end);

            leftTask.fork();
            rightTask.fork();

            int leftResult = leftTask.join();
            int rightResult = rightTask.join();

            sum = leftResult + rightResult;

        }
        return sum;
    }

    public static void main(String[] args) throws ExecutionException, InterruptedException {
        ForkJoinPool forkJoinPool = new ForkJoinPool();
        CountTask task = new CountTask(1,4);
        Future<Integer> result = forkJoinPool.submit(task);
        try {
            System.out.println(result.get());
        }catch (Exception e){

        }
    }
}


4節:13個操做原子類

concurrent包下面atomic包提供了13個類,屬於4種類型的原子更新方式

  1. 原子更新基本類型

  2. 原子更新數組

  3. 原子更新引用

  4. 原子更新屬性

基本都是使用Unsafe實現的包裝類

5節:併發工具類

等待多線程完成的CountDownLatch

容許一個或者多個線程等待其餘線程完成操做

同步屏障CyclickBarrier

讓一組線程到達一個屏障後阻塞,直到最後一個線程到達屏障纔會開門

控制併發線程數的Semaphore

控制同時訪問特定資源的線程數量

線程間交換數據Exchanger

提供一個同步點,在這個同步點,兩個線程之間能夠交換數據

相關文章
相關標籤/搜索