并发
并发:
- 多个线程操作相同的资源,保证线程安全,合理使用资源。
高并发:
- 服务能同时处理很多请求,提高程序性能。
高并发问题展示代码:
@Slf4j
public class concurrency1 {
//并发量数值
private static int threadTotal = 2000;
//并发量数据上线
private static int clientTotal = 50000;
//真实并发数量
private static long count = 0;
public static void main(String[] args) {
/**
* Java线程池 通过Executors提供的四项线程池,分别是:
* newCachedThreadPool创建一个可缓存线程池: 如果线程池长度超过处理需求,可灵活回收空闲线程,若无可回收,测新建线程。
* newFixedTRhreadPool创建一个定长线程池: 可控制线程最大并发数,超出的线程会在队列中等待。
* newScheduledThreadPool创建一个定长线程池: 支持定时及周期性任务执行.
* newSingleThreadExecutor创建一个单线程化的线程池: 他智慧使用唯一的工作线程来执行,保证所有任务按照指定顺序(FIFO,LIFO,优先级)执行.
*/
//当时使用可缓存线程池
ExecutorService executorService = Executors.newCachedThreadPool();
/**
* java 并发核心 Semaphore
* Semaphore 是什么? 能做什么?
* Semaphore 是 synchronnized 的加强版,作用就是控制线程的并发数量.
*/
//当前代码控制并发量在同时请求在2000.
final Semaphore semaphore = new Semaphore(threadTotal);
for (int i = 0 ; i < clientTotal; i++){
executorService.execute(() -> {
try {
//调用acquire获取许可,才能继续执行,如果获取失败,则进入阻塞,处理完成后调用release释放许可。
semaphore.acquire();
show();
//调用release释放许可。
semaphore.release();
} catch (Exception e) {
log.info("Exception=",e);
}
});
}
//Semaphore第一阶段调用 shutdown 拒绝传入任务
executorService.shutdown();
//然后调用 shutdownNow(如有必要)取消所有遗留的任务:
//executorService.shutdownNow();
log.info("count={}",count);
}
public static void show(){
count++;
}
}
案例统计结果存在问题:
11:11:22.151 [main] INFO com.tiandongxue.serviceconcurrency.concurrency1 - count=4883
Process finished with exit code 0
底层原理:
- CPU 多级缓存 cache CPU的频率太快,快到主存跟不上,这样在处理器时钟周期内,CPU常常需要等待主存,浪费资源。所以cache的出现是为了缓解CPU和存储之间速度的不匹配问题(结构: CPU → cache → memory)
CPU cache缓存存在的意义:
-
时间局部性:如果某个数据被访问,那么在不久的将来他很可能被再次访问。
-
空间局部性:如果某个数据被访问,那么与其相邻的数据很快也可能被访问。
- 多核CPU多级缓存一致性(MESI = Modified Exclusive Shared Or Invalid):如何保证缓存内部数据的一致性,不让系统数据混乱,这里引出了一个一致性的协议MESI
CPU中每个缓存行(caceh line)使用4种状态进行标记:
-
M: 被修改(Modified)
该缓存行只被缓存在该CPU的缓存中,并且是被修改过的(dirty),即与主存中的数据不一致,该缓存行中的内存需要在未来的某个时间点(允许其它CPU读取请主存中相应内存之前)写回(write back)主存。
当被写回主存之后,该缓存行的状态会变成独享(exclusive)状态。
-
E: 独享的(Exclusive)
该缓存行只被缓存在该CPU的缓存中,它是未被修改过的(clean),与主存中数据一致。该状态可以在任何时刻当有其它CPU读取该内存时变成共享状态(shared)。
同样地,当CPU修改该缓存行中内容时,该状态可以变成Modified状态。
-
S: 共享的(Shared)
该状态意味着该缓存行可能被多个CPU缓存,并且各个缓存中的数据与主存数据一致(clean),当有一个CPU修改该缓存行中,其它CPU中该缓存行可以被作废(变成无效状态(Invalid))。
-
I: 无效的(Invalid)
该缓存是无效的(可能有其它CPU修改了该缓存行)。
转载图片
- 更详细的中文文档描述可以查看转载原文:Cache一致性协议 与 MESI.