老师你好,能具体描述一下i++为什么不是线程安全的吗?

来源:5-1 用不好 Synchronized 关键字

muffinfeng

2020-09-08

老师你好,能具体描述一下i++为什么不是线程安全的吗?

写回答

2回答

张勤一

2020-09-09

muffinfeng 你好:

    其实这个 i++ 或者 ++i 不是线程安全的问题也是面试常见的一个问题。我在此详细的解释下这个问题。

    i++不是原子操作,也就是说,它不是单独一条指令,而是3条指令(3条汇编指令):

        1. 从内存中把i的值取出来放到CPU的寄存器中

        2. CPU寄存器的值+1

        3. 把CPU寄存器的值写回内存

    由于线程共享栈区,不共享堆区和全局区,所以当且仅当 i 位于栈上是安全的,反之不安全(++i 也同理).   因为如果是全局变量的话,同一进程中的不同线程都有可能访问到。对于读值,+1,写值这三步操作,在这三步任何之间都可能会有 CPU 调度产生,造成 i 的值被修改,造成脏读脏写。

    其实,最核心的就是这个 +1 的过程不是原子的,任何一个线程都可以打断这个过程,一旦打断,其他线程看到的值可能是落后的了。

    那么,对于 value-- 或者 --value 也就是一个道理了。-1 的过程不是原子的,多线程的调度不可预知,那么,线程在操作的过程中看到的值不是最新的,所以,就会存在一直减到负值的情况了。


    我是勤一,致力于将这门课程的问答区打造为 Java 知识体系知识库,Java 知识体系 BBS!共同建造、维护这门课程,我需要每一个你!


2
4
qq_l_648
请教了一哥,应该是由于线程不共享栈区,共享堆区和全局区,所以当且仅当 i 位于栈上是安全的,反之不安全(++i 也同理).
2021-03-12
共4条回复

muffinfeng

提问者

2020-09-08

还有的话就是我不明白为什么这里value--之后会返回负数呢

1
0

Java实操避坑指南 SpringBoot/MySQL/Redis错误详解

掌握业务开发中各种类型的坑,,Java web开发领域通用

466 学习 · 204 问题

查看课程