百科问答小站 logo
百科问答小站 font logo



是否有文档支持Java『volatile int i 在执行 i++ 的底层是非原子性的三步』的说法? 第1页

  

user avatar   bei-ji-85 网友的相关建议: 
      

volatile

A Java keyword used in variable declarations that specifies that the variable is modified asynchronously by concurrently running threads.



根本没写原子操作的事情


user avatar   s.invalid 网友的相关建议: 
      

原子性很昂贵的。


不要问“有没有文档支持volatile int i在执行i++时没有原子性”,而应该是“没有文档明确承诺原子性时,请一定要默认相关操作没有原子性”——包括从内存读入一个int到寄存器,哪怕这一个动作你都不能默认它有原子性(假如没有字节对齐,load i 还真有可能得分两次执行)。


补充一点:不要靠查汇编来自行得出结论,这是个错误的方法。


很多时候,某个版本、某种CPU的某个工作模式下得出的结论,在下一个版本、另一种CPU甚至同种CPU的不同工作模式下就是错的。

这是因为,现代编译器极其智能,可以根据上下文任意改变指令顺序甚至删除、合并指令——只要最终执行结果语义等价。类似的,CPU自己也可能乱序执行你的程序,只要语义等价。

这样做反而是极其有益的。灵活的执行策略才能允许编译器生成最高效的程序、让CPU因地制宜的根据实际情况实时选择最优执行方案。

你不应该依赖后面的细节。这相当于你要求编译器/CPU死板的生成和执行你的程序。而这反而是做不到的,因为编译器/CPU已经被设计成智能模式了,没人能保证它总是按上一次的方式执行。


但反过来却是有保证的。无论CPU还是编译器文档,它们都会向你承诺一些操作的语义——不管执行过程多么花样百出,这些语义是可以100%保证的。它是你唯一可以信赖的东西。


因此,正如Linus所说,把事情做对的方式只有两个:

其一是找到正式文档,确保文档中给了清晰无歧义的承诺;

其二是做大量的实验,尽可能覆盖市面上所有的CPU所有的工作模式、所有的软件环境以及所有的应用场景/传入参数,只有所有这些测试全都通过(或者少量未能通过)时,我们才可以说这个做法是有效的(同时还要列出哪些情况下会失效)——然后,每当软件更新/CPU升级,我们就不得不重复这些测试,这才能宣布我们的软件可以支持新的软硬件环境。


一般来说,写一个新软件、或者为旧软件添加新功能时,应该遵循策略一,不要依赖任何未经确认的假设,这样才可能写出健壮的程序。

而维护旧软件时,可能就不得不依赖策略二——但这种代码很容易搞成“屎山”,因此可能不得不想办法搞好隔离;同时尽量避免任何新代码依赖同样的假设(哪怕它已经被大量的使用/测试证明在大多数系统上工作的很好)。否则一旦在某个新环境出现了问题,改起来那可真是……




  

相关话题

  如何看待腾讯云正式对外公布分布式云战略,发布云原生操作系统遨驰 Orca ,会给业界带来哪些影响? 
  甲骨文诉谷歌案,法院裁决 Java API 受版权保护,这是破坏性先例吗? 
  .NET 和 Java 在 Web 开发上各有什么优缺点? 
  Linux和Windows可以安装在任何个人电脑上,而安卓却需要为每台设备定制一个版本的原因是什么? 
  服务器集群为什么节点间通信为什么要用到RPC,这个是为了解决什么问题? 
  windows有更方便的IDE进行开发, 为什么互联网公司的服务器还是用linux? 
  Unix网络编程里的阻塞是在操作系统的内核态创建一个线程来死循环吗? 
  用数据线连接手机和电脑后,可以在手机上访问电脑硬盘中的文件吗? 
  除了跨平台和平台成本以外,Java 还有什么特性是 C# 不具备的? 
  自动注入到底比new好在哪? 

前一个讨论
特斯拉选择 Linux 作为车载系统的原因是什么?
下一个讨论
2021年了,你还在玩游戏《闪耀暖暖》么,为什么?





© 2024-12-23 - tinynew.org. All Rights Reserved.
© 2024-12-23 - tinynew.org. 保留所有权利