问题场景描述:
对选课系统接口进行压测,发现出现选课数量击穿问题。设置好的课程数量普通测试时候,并不会出现问题,但并发测试的时候出现了课程超选的问题,选课数量出现了负数,超过选课数量的人选到了课程。
设置的是模拟20位用户选择,数量只有5个的课程。测试结果20名用户都选到了课程,课程数量变为-15个。
问题分析:
以下是选课的核心逻辑代码,以下代码并不是线程安全的,当出现高并发时候,会出现等值击穿问题和数据不一致的问题。当一个线程还在查是否有课程时候,另一个线程已经将数据减一了,所以必须加锁。
问题解决
在代码处加入synchronized关键字,对需要同步的代码进行加锁,来保证线程逐个执行。
测试结果是数据库也保证了只用5个用户选到了课程。
问题总结与思考
1、synchronized加锁在保证代码正确的情况下,尽量保证粒度细一些,锁的代码少一点。
2、在进行类似的等值判断是否减到0的场景中,要用小于0来进行判断,如果用等于号,万一等值击穿将会一发不可收拾。
3、synchronized加锁在大量请求争抢锁的情况下,而处理时间时间又比较长,会出现锁升级的情况,大量升级为重量级锁将会导致系统性能下降。
4、也可以考虑用ReetrantLock锁和数据库层面进行加锁,进行优化。
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。