目录结构
抽象类:求和器
单线程 求和器 VS 多线程 求和器
1)线程池
- 多个线程 一起并发执行,性能很生猛
2)CountDownLatch
主线程 使用 latch.await() 阻塞住,直到所有 子任务 都执行完毕了,才会继续向下执行。这样就保证了 逻辑的正确性
所有 子任务 共享同一个 CountDownLatch 变量,实现 协同合作
所有 子任务 的 finally块 中,必须要 latch.countDown() ,确保 "无论 正确、异常 都会 countDown",否则 主线程 会由于 "某一个 子任务 没有 countDown 过,就 执行结束了,导致 latch 最终无法被 countDown 到 0 ",而被 永远挂住
扫描二维码关注公众号,回复: 4223571 查看本文章
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();
}
}