反射会在java中保持volatile的语义吗
例如,当我修改一个线程中的volatile字段时,JMM将保证新值对另一个线程可见 我的问题是,当我使用反射来修改字段时,这仍然是真的吗 下面的代码只是一个示例,演示反射是如何工作的反射会在java中保持volatile的语义吗,java,reflection,volatile,Java,Reflection,Volatile,例如,当我修改一个线程中的volatile字段时,JMM将保证新值对另一个线程可见 我的问题是,当我使用反射来修改字段时,这仍然是真的吗 下面的代码只是一个示例,演示反射是如何工作的 public class ReflectionDemo { private volatile boolean flag = false; public static void modify(ReflectionDemo target, boolean value) { try {
public class ReflectionDemo {
private volatile boolean flag = false;
public static void modify(ReflectionDemo target, boolean value) {
try {
Field field = ReflectionDemo.class.getDeclaredField("flag");
field.setAccessible(true);
field.setBoolean(target, value);
} catch (NoSuchFieldException | IllegalAccessException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
ReflectionDemo demo = new ReflectionDemo();
System.out.println(demo.flag);
ReflectionDemo.modify(demo, true);
System.out.println(demo.flag);
}
}
摘自评论
是的,通过反射对volatile
字段的更改将对其他线程可见,就像标准访问一样。这是因为反射API生成JVM字节码来执行操作,因此对字段本身的访问仍然是不稳定的
违反volatile语义的唯一方法是通过
sun.misc.Unsafe
API。是的,只有使用Unsafe
才能更改volatile语义。@PeterLawrey换句话说,Unsafe
API不在乎字段是否被volatile修改。当我使用putXXVolatile()
时,我得到了volatile语义保证,当我使用putXX()
时,我什么都没有得到。这是真的吗?@PeterLawrey,这是在Java语言规范还是Java虚拟机规范中定义的?我想进一步了解这个问题。操作选择语义。反射生成字节码以高效的方式为您执行操作,但是访问仍然是一样的。JLS没有定义任何单个库的行为,只有Javadoc定义。