干货!线程池+CountDownLatch,实现 多线程并发计算、汇总

目录结构

抽象类:求和器

单线程 求和器 VS 多线程 求和器

1)线程池

  • 多个线程 一起并发执行,性能很生猛

2)CountDownLatch

  • 主线程 使用 latch.await() 阻塞住,直到所有 子任务 都执行完毕了,才会继续向下执行。这样就保证了 逻辑的正确性

  • 所有 子任务 共享同一个 CountDownLatch 变量,实现 协同合作

  • 所有 子任务 的 finally块 中,必须要 latch.countDown() ,确保 "无论 正确、异常 都会 countDown",否则 主线程 会由于 "某一个 子任务 没有 countDown 过,就 执行结束了,导致 latch 最终无法被 countDown 到 0 ",而被 永远挂住

3)private AtomicInteger sum

  • 多个线程 会并发 操作同一个 Integer 类型变量,为了确保 线程安全,要使用 Atomic 原子类型

源码

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();
    }


}

猜你喜欢

转载自my.oschina.net/u/2602893/blog/2876935
今日推荐