1️⃣前言
在开始真正的讲解以前,我们实现一个简单的场景-实现一个计数功能
计数功能 : CountExample
@Slf4j
public class CountExample {
// 请求总数
public static int clientTotal = 5000;
// 同时并发执行的线程数
public static int threadTotal = 200;
public static int count = 0;
public static void main(String[] args) {
ExecutorService exec = Executors.newCachedThreadPool();
final Semaphore semaphore = new Semaphore(threadTotal);
for (int index = 0; index < clientTotal ; index++) {
exec.execute(() -> {
try {
semaphore.acquire();
add();
semaphore.release();
} catch (Exception e) {
log.error("exception", e);
}
});
}
exec.shutdown();
log.info("count:{}", count);
}
private static void add() {
count++;
}
}
计数功能 : MapExample
@Slf4j
public class MapExample {
private static Map<Integer, Integer> map = Maps.newHashMap();
// 请求总数
public static int clientNum = 5000;
// 同时并发执行的线程数
public static int threadNum = 200;
public static void main(String[] args) throws Exception {
ExecutorService exec = Executors.newCachedThreadPool();
final Semaphore semaphore = new Semaphore(threadNum);
for (int index = 0; index < clientNum ; index++) {
final int threadNum = index;
exec.execute(() -> {
try {
semaphore.acquire();
func(threadNum);
semaphore.release();
} catch (Exception e) {
log.error("exception", e);
}
});
}
exec.shutdown();
log.info("size:{}", map.size());
}
private static void func(int threadNum) {
map.put(threadNum, threadNum);
}
}
CountExample运行结果 MapExample运行结果从上面两个demo的运行结果可以看出,并发情况下每一次的运行结果都是小于5000的,且每次都有可能会不一样(大家可以多尝试几次就会发现,值一直会小于5000且可能每次值都不一样),那么我们如果把两个demo同时允许的进程数修改为1又会是什么样的呢?
从以上实例中我们可以看到,当我们在多线程并发的情况下执行一个简单的累加操作,出错的概率非常的高,这个时候我们就需要思考一下并发环境下到底应该如何编码?到底有哪些手段可以保证并发下的结果是正确的?
2️⃣并发与高并发的基本概念
并发
同时拥有两个或者多个线程,如果程序在单核处理上运行,多个线程将交替地换入或者换出内存,这些线程是同时"存在"的,每个线程都处于执行过程中的某个状态,如果运行在多核处理器上,此时,程序中的每个线程都将分配到一个处理器核上,因此可以同时运行;
高并发
高并发(High Concurreny)是互联网分布式系统架构设计中必须考虑的因素之一,它通常是指,通过设计保证系统能够同时并行处理很多请求;
基本概念
单纯的说概念可能有点难以理解,我们来简单对比一下并发与高并发;当我们说多线程并发时我们谈论的是什么呢?其实更多的是讨论多个线程操作相同的资源,这个时候我们谈论的点多数情况下是落实在保证线程安全,合理分配或者使用资源上边;那么当我们谈论高并发时我们谈论的又是什么呢?高并发主要是指系统运行过程中短时间内要大量操作请求的情况,它主要发生在系统集中收到了大量的请求比如12306以及天猫的双十一;这种情况的发生会导致系统在这段时间内会执行大量的操作,例如对资源的请求对数据库的操作等等,如果高并发处理不好不仅仅会降低用户的体验度(请求时间变长)同时也有可能会导致系统宕机,严重的甚至会导致OOM异常 系统停止工作等情况;如果想要系统适应高并发的状态,就要从多个方面对系统进行优化,包括硬件 网络 系统架构以及开发语言的选取 数据结构的运用 算法的优化 数据库优化等等;这个时候我们谈论的更多的是如何提高现有程序的性能,更多的是对高并发场景提高一些解决方案 思路 手段;
网友评论