反射会在java中保持volatile的语义吗

反射会在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 {

例如,当我修改一个线程中的volatile字段时,JMM将保证新值对另一个线程可见

我的问题是,当我使用反射来修改字段时,这仍然是真的吗

下面的代码只是一个示例,演示反射是如何工作的

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定义。