面试官:单核服务器可以不加锁吗?

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

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

1. 问题答案

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

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

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

2. 原因分析

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

  • 查询 i 的值。
  • 执行 i+1 修改操作。
  • 将结果赋值给 i 变量。

如果是加锁操作,那么线程可以一个个执行,首先某一个线程先把 i 修改为 1,然后另一个线程再次基础上将结果修改为 2。

但如果不加锁,那么就会导致下面的问题:


线程 1

线程 2

t1

读取到 i 的值为 0


t2


读取到 i 的值为 0

t3


执行 +1 操作,修改 i 为 1

t4


将结果 1  赋值给 i 变量

t5

执行 +1 操作,修改 i 为 1


t6

将结果 1  赋值给 i 变量


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

责任编辑:姜华 来源: 磊哥和Java
相关推荐

2020-08-10 07:49:51

服务器

2022-10-10 12:31:37

服务器性能

2024-07-22 14:09:22

@AsyncJava

2023-08-13 16:17:31

2023-07-11 16:01:47

共享数据开发

2020-10-15 06:26:24

高并发场景冰河

2022-08-02 06:31:32

Java并发工具类

2022-07-26 08:40:42

Java并发工具类

2019-07-24 11:52:11

CPU服务器面试官

2022-07-11 10:47:46

容器JAVA

2022-06-30 08:14:05

Java阻塞队列

2022-05-23 08:43:02

BigIntJavaScript内置对象

2024-03-12 14:36:44

微服务HTTPRPC

2015-08-13 10:29:12

面试面试官

2023-02-26 17:21:21

2014-11-28 16:04:36

浪潮

2021-04-12 21:34:29

Redis故障数据

2024-01-10 15:27:58

SessionCookieWeb 应用

2021-09-08 08:06:57

Redis原子性数据类型

2020-05-11 14:55:44

CSS鼠标前端
点赞
收藏

51CTO技术栈公众号