为什么需要学习 Java 并发?
从提升性能角度来说
- 提升了对CPU的使用效率 :目前生产的服务器大多数都是多核,标配的机器都是 8C/16G。操作系统会将不同的线程分配给不同的核心处理,理论上,有多少核心就有多少个线程并行执行。如果没有并发编程,CPU的利用率将极大的浪费,假设当前正在处理耗时的 I/O 操作,那么整个CPU就会处于阻塞空闲状态,后面的指令必须等待前面的执行完才能继续执行。
- 降低服务 RT :大型互联网访问量轻松每秒轻松过万,如果没有并发处理,所有的用户请求都会排队等待,那种体验效果你能想象么,这样的服务能力如何能留住客户?有了并发编程,充分释放CPU算力,操作系统让每个客户轮流使用CPU计算,每个客户都能得到快速的响应。
- 容错率高 :线程与线程之间的执行不会相互干扰,某个线程执行出现异常退出,不会对其它线程造成影响。
<!-- more -->
从开发者角度来说
- Java 基础面试必考察技能 :Java 并发面试问题基本必出现,有大型项目研发经验的同学,处理并发问题多的同学,往往会被青睐。因为越是复杂的系统,并发请求就越多,简单的业务 + 并发 = 这个业务不简单。
- 工作中离不开并发 :多线程能充分发挥CPU的计算力,这使得我们不得不了解并发的原理,以免造成线程安全问题,给生产带来损失。常用的中间件中大量运用了并发知识,如 MQ、RPC等,如果不熟悉原理,如何能够调优中间件的使用。
并发编程业务中的实践
实践一:风控规则引擎——策略执行
互联网企业风控安全部门每时每刻都需要和黑灰产对抗,保护企业遭受不必要的经济损失。风控策略团队在对抗的过程中,沉淀出一系列风险识别策略,用以检测当前业务请求中否存在高危操作。
风控安全团队需要评估业务在运行流程中,是否存在黑产能够获取利益点的地方,即“ 风险卡点 ”。评估后,需要业务在每次流程经过风险卡点处,需透传业务信息给风控服务,风控服务在很多时间内进行大量决策计算,并返回业务方决策结果(ACCEPT-通过/REVIEW-人工,需进一步信息确认/REJECT-拒绝,高危操作)。如图展示的是营销活动——裂变类活动风险卡点。
营销裂变流程风险卡点图
一条业务请求耗时一般在 300 ~ 500 ms 之间,如果超过这个区间,可能就需要定位调优哪个节点耗时高了。大型互联网公司系统架构比较复杂,完整的业务可能有几十甚至上百个服务系统,你触发的一次请求,可能中途会经过多少服务超过你想象。
如上述,业务对风控服务的性能要求很高,一般控制在 100 ms 以内。但风控内部排查业务请求涉及大量策略和规则,如何短时间内执行完,且又不阉割策略呢?答案是并发变成。风控内部大量使用并发,以满足海量请求和计算需求,我将以策略规则的执行来举例如何编写编发变成代码。如下是风控服务一次请求的大致执行流程:
风控流程执行图
可以看到,一次风控请求的判定,涉及大量的规则判定,此时如果没有并发,会出现什么效果?
串行&并行执行规则图
全部串行执行策略和规则的话,可能几秒都不定能计算出来,此时我们需要使用 Java 并发来满足性能需求。 核心代码如下:
public class RuleSessionExecutor { // 线程池 private final static ExecutorService executor = new ThreadPoolExecutor( Runtime.getRuntime().availableProcessors() * 8, Runtime.getRuntime().availableProcessors() * 8, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>