当前位置: 首页 > article >正文

《Java核心技术I》volatile字段

volatile字段

  • 有多处理器的计算机能够暂时在寄存器或本地内存缓存中保存内存值,其结果是,运行在不同处理器上的线程可能看到同一个内存位置上有不同的值。
  • 编译器可以改变指令执行的顺序以使吞吐量更大化,编译器不会选择可能改变代码语义的顺序,但编译器有一个假定,认为内存值只在代码中有显式的修改指令时才会改变,然而,内存值有可能被另一个线程改变。

注释:Brian Goetz创造了以下"同步格言",如果写一个变量,这个变量接下来可能会被另一个线程读取,或者,如果读一个变量,而这个变量可能已经被另一个线程写入值,那么必须使用同步。

volatile关键字为实例字段的同步访问提供了一种免锁机制。

如果声明一个字段为volatile,那么编译器和虚拟机就知道该字段可能被另一个线程并发更新。

例如,假设一个对象有一个boolean标记done,它的值由一个线程设置,而由另一个线程查询,你可以使用锁:

private boolean done;

public synchronized boolean isDone(){ return done; }

public synchronized void setDone(){ done = true; }

或许使用内部对象锁不是个好主意,如果另一个线程对该对象加锁,isDone和setDone方法可能会阻塞。如果这是个问题,可以只为这个变量使用一个单独的锁,但这很麻烦。

这种情况下,将字段声明为volatile就很合适:

private volatile boolean done;

public boolean isDone(){ return done; }

public void setDone(){ done = true; }

编译器会加入适当代码,确保如果一个线程对done变量做了修改,这个修改对读取这个变量的所有其他线程都可见。

警告:volatile不能提供原子性,例如,方法public void flipDone(){ done = !done }不能确保翻转字段中的值,不能保证读取,翻转和写入不被中断。


http://www.kler.cn/a/427774.html

相关文章:

  • 【数据库】MySQL的安装与卸载
  • 让服务器更“隐身”的秘密武器:端口敲门技术
  • XSS(DOM)-HIGH错误总结
  • CVPR和其他2024顶会论文阅读(资源整理【1】)
  • element-plus的el-tree的双向绑定
  • 【MySQL 进阶之路】InnoDB引擎详解
  • 3D 生成重建015-Feature 3DGS理解3DGS场景内的一切
  • 软件工程——期末复习(4)
  • 同道猎聘Q3营收降利润增,AI或成估值重塑关键词
  • JAVA设计模式,工厂模式
  • gitlab-cicd部署安装与具体操作
  • 在visio2021 中插入MathType公式
  • 【bug】pymysql.err.OperationalError: (1046, ‘No database selected‘)
  • React16搭建-GPT回答
  • 游戏引擎学习第36天
  • [Flutter]Json序列化json_serializable使用属性全介绍
  • 嵌入式蓝桥杯学习4 lcd移植
  • 【Linux】09 -- Linux下的shell编程(一)
  • 针对xpath局限的解决方案
  • 室联人形机器人:家政服务任务结构化、技术要点、深入应用FPGA的控制系统框架设计(整合版)