乾貨!線程池+CountDownLatch,實現 多線程併發計算、彙總

目錄結構java

抽象類:求和器安全

單線程 求和器 VS 多線程 求和器多線程

1)線程池併發

  • 多個線程 一塊兒併發執行,性能很生猛

2)CountDownLatchide

  • 主線程 使用 latch.await() 阻塞住,直到全部 子任務 都執行完畢了,纔會繼續向下執行。這樣就保證了 邏輯的正確性性能

  • 全部 子任務 共享同一個 CountDownLatch 變量,實現 協同合做this

  • 全部 子任務 的 finally塊 中,必需要 latch.countDown() ,確保 "不管 正確、異常 都會 countDown",不然 主線程 會因爲 "某一個 子任務 沒有 countDown 過,就 執行結束了,致使 latch 最終沒法被 countDown 到 0 ",而被 永遠掛住atom

3)private AtomicInteger sum線程

  • 多個線程 會併發 操做同一個 Integer 類型變量,爲了確保 線程安全,要使用 Atomic 原子類型

源碼3d

SinglethreadSummator

package com.lsy.test;


/**
 * 單線程 求和器
 */
public class SinglethreadSummator extends Summator{

    private int sum = 0;

    private int getValue() {
        System.out.println("SinglethreadSummator.getValue()");
        try {
            Thread.sleep(400);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return 1;
    }

    @Override
    public int sum(int count) {

        for(int i=0; i<=count-1; i++) {
            sum = sum + getValue();
        }

        return sum;

    }



}

MultithreadSummator

package com.lsy.test;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.atomic.AtomicInteger;

/**
 * 多線程 求和器
 */
public class MultithreadSummator extends Summator{

    private AtomicInteger sum = new AtomicInteger(0); //因爲是 多線程,因此要使用 原子類型
    private int corePoolSize = 10;

    public int getValue() {
        System.out.println("MultithreadSummator.getValue()");
        try {
            Thread.sleep(400);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        return 1;
    }


    /**
     * 內部類
     */
    private class Core implements Runnable {
        private CountDownLatch latch;

        public Core(CountDownLatch latch) {
            this.latch = latch;
        }

        @Override
        public void run() {

            try {

                sum.getAndAdd(getValue());

            } catch (Exception e) {
                e.printStackTrace();
            } finally {
                latch.countDown(); //不管 正確 或 異常,都必須 countDown,不然 main線程 會被 countDown.await() 一直掛住
            }

        }
    }

    @Override
    public int sum(int count) {

        CountDownLatch latch = new CountDownLatch(count);

        ExecutorService service = Executors.newFixedThreadPool(corePoolSize);

        try {

            //發起 count個 任務,併發執行
            for(int i=0; i<=count-1; i++) {
                service.submit(new Core(latch));
            }

            //等待 全部線程 都 執行完畢
            latch.await();

        } catch (InterruptedException e) {
            e.printStackTrace();
        } finally {
            service.shutdown();
        }

        return sum.get();
    }


}
相關文章
相關標籤/搜索