i++不是原子操作,也就是说,它不是单独一条指令,而是3条指令(3条汇编指令):
1、从内存中把i的值取出来放到CPU的寄存器中
2、CPU寄存器的值+1
3、把CPU寄存器的值写回内存
由于线程共享栈区,不共享堆区和全局区,所以当且仅当 i 位于栈上是安全的,反之不安全(++i也同理). 因为如果是全局变量的话,同一进程中的不同线程都有可能访问到。对于读值,+1,写值这三步操作,在这三步任何之间都可能会有CPU调度产生,造成i的值被修改,造成脏读脏写。
volatile不能解决这个线程安全问题。因为volatile只能保证可见性,不能保证原子性。