ovi*_*miu 5 java getter multithreading volatile
我想知道私有布尔字段的getter方法是否强制其他线程获取最新的更新值?这是不稳定场的替代品吗?例如:
Class A {
private boolean flag;
public boolean getFlag() {
return this.flag;
}
public void setFlag(boolean flag) {
this.flag = flag;
}
}
Run Code Online (Sandbox Code Playgroud)
VS
Class B {
public volatile boolean flag;
}
Run Code Online (Sandbox Code Playgroud)
编辑: 整个对象是否被线程(包括私有字段)缓存是真的,所以当我调用getter时它会返回缓存的私有字段吗?
不,getter 不会导致字段同步。
当谈论在多线程环境中读写原语时,我们遇到三个由CPU引起的问题
Getter 并不能解决这些问题。即使是这样,JIT 编译器也可能会完全优化该函数。那又如何?
挥发性是解决上述问题的方法之一。锁也是如此。它们确保一个线程读取原语的最新值,或者确保正在写入的值对其他线程可见。它们还使汇编指令完全按照编译时的方式运行,没有任何混合。
附带说明一下,生成的程序集可能看起来与您在代码中编写的程序集完全不同。你问自己“我在代码中编写了要从中读取的内容flag,那么为什么程序不从该字段本身读取呢?” 编译器可以做任何它认为合适的事情来使汇编尽可能快。通过不添加任何锁或易失性说明符,您基本上告诉编译器不涉及多线程访问,并且编译器(以及随后的 CPU)可以自由地假设该对象没有被多个线程触及。可能这个对象一开始就没有被创建。JIT 编译器可能会说“好吧,在寄存器中声明这个布尔值并将其视为整个对象”。这是很有可能的。
编辑:整个对象是否真的由线程缓存(包括私有字段),以便当我调用 getter 时它会返回缓存的私有字段?
你不能这样假设。它取决于 JVM、底层操作系统和底层 CPU。它可能被完全、部分或根本不缓存。提醒一下,大多数CPU都有不止一个缓存行,即使对象被缓存,它缓存在哪里呢?在寄存器或高速缓存行之一中?