Java中volatile的作用与意义
使用场景(单写多读)
在多线程环境中。假设在多线程的情况下有一个共享变量num(初始值为0),环境中的线程分为两大类:一类是对num的写线程writeThreads(如果要保证线程安全性,写线程只能有一个,或采用其他同步机制);一类是对num的读线程readThreads。业务要求:读的业务需要展示实时的num值。
Java内存模型规定所有的变量都是存在主存当中,每个线程都有自己的工作内存,运行时,线程会从主存中拷贝一份变量值到自己的工作内存中,当其他线程修改了变量值,写回主存,其他线程并不会有感知,这样就导致了数据的不一致性。
当我们在变量前加上volatile后,当有线程修改了变量值,其他线程需要再次使用到变量时,就会去主存中获取实时的变量值,而不会再使用自己工作内存中保存的变量副本。
注意点:如果多个线程都是对变量的写操作,且是依赖变量自身的写操作(依赖自身:num=num+1; 不依赖自身:num=1;),volatile仍然没法保证变量的线程安全,volatile只是一种轻量级的同步机制,多个线程写操作时,仍然会出现相互覆盖主存中的值。
如下图中,由于各个线程对主存中的值回写覆盖,导致了最终结果与预期值相差300多。
避免指令重排
。。。。。待完善