我正试图理解Java volatile的本质及其语义,以及它对底层架构和指令的转换。如果我们考虑以下博客和资源:
- 为volatile生成栅栏 - 读写volatile所生成的内容 - 关于栅栏的stackoverflow问题 这是我收集到的信息:
- volatile读会在之后插入loadStore/LoadLoad屏障(x86上的LFENCE指令) - 它防止加载与后续写入/加载的重新排序 - 它应该保证加载由其他线程修改的全局状态,即在LFENCE之后,其他线程所做的状态修改对当前线程在其CPU上可见。
我难以理解的是:Java在x86上不会发出LFENCE指令,即读取volatile不会导致LFENCE。我知道x86的内存排序可以防止加载与加载/存储的重新排序,因此第二个要点已经得到了处理。但是,我认为为了使状态对此线程可见,应该发出LFENCE指令,以确保在栅栏之后执行的下一条指令之前,所有LOAD缓冲区都已被清空(根据英特尔手册)。我知道x86上有高速缓存一致性协议,但是volatile读取仍应清空缓冲区中的任何LOAD,请问这是为什么?
- 为volatile生成栅栏 - 读写volatile所生成的内容 - 关于栅栏的stackoverflow问题 这是我收集到的信息:
- volatile读会在之后插入loadStore/LoadLoad屏障(x86上的LFENCE指令) - 它防止加载与后续写入/加载的重新排序 - 它应该保证加载由其他线程修改的全局状态,即在LFENCE之后,其他线程所做的状态修改对当前线程在其CPU上可见。
我难以理解的是:Java在x86上不会发出LFENCE指令,即读取volatile不会导致LFENCE。我知道x86的内存排序可以防止加载与加载/存储的重新排序,因此第二个要点已经得到了处理。但是,我认为为了使状态对此线程可见,应该发出LFENCE指令,以确保在栅栏之后执行的下一条指令之前,所有LOAD缓冲区都已被清空(根据英特尔手册)。我知道x86上有高速缓存一致性协议,但是volatile读取仍应清空缓冲区中的任何LOAD,请问这是为什么?