今天有位同学问了磊哥一个问题,大概的意思是“单核服务器可以不加锁吗?”,我觉得很有意思,所以在这里就和各位探讨一下:

1. 问题答案

先说我的理解,单核服务器仍然需要加锁

因为在单核服务器上也会有线程切换,如果不加锁,那么线程切换后,另一个线程就可以访问其他线程未操作完的共享变量,这就会导致操作的共享变量发生数据覆盖的问题,所以是需要加锁。

例如,以下案例,线程 T1 和线程 T2 都要执行 i++ 操作,i 的初始值为 0,所以正确的执行结果应该是 2。但如果不加锁,即使在单核服务器下也会造成数据覆盖问题,最终的执行结果为 1 的情况,具体执行流程如下:

2. 原因分析

因为 i++ 并不是原子操作,它的执行要分为以下 3 步:

线程 1线程 2
t1读取到 i 的值为 0
t2读取到 i 的值为 0
t3执行 +1 操作,修改 i 为 1
t4将结果 1 赋值给 i 变量
t5执行 +1 操作,修改 i 为 1
t6将结果 1 赋值给 i 变量

从上述执行流程可以看出,即使在单核服务上,依然会发生线程切换的问题。而线程切换就可能会导致数据覆盖的问题,这就是线程安全问题,所以单核服务器也要加锁

课后思考

除了锁机制外,还有哪些手段可以保证线程安全?

特殊说明

以上内容来自我的《Java 面试突击训练营》,这门课程是有着十几年工作经验(前 360 开发工程师),10 年面试官经验的我,花费 4 年时间打磨完成的一门视频面试课。学完训练营的课程之后,基本可以应对目前市面上绝大部分公司的面试了,并且课程配备了 9 大就业服务,帮助上千人找到 Java 工作,其中上百人拿到大厂 Offer,学员最高薪资 70W 年薪,面试课目录和 9 大服务如下:

加我微信咨询:vipStone【备注:训练营】