反射会在java中保留volatile的语义

例如,当我在一个线程中修改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);
    }

}

最佳答案 摘自评论

是的,通过反射对易失性字段的更改将对其他线程可见,就像标准访问一样.这是因为反射API生成JVM字节代码以执行操作,因此对字段本身的访问仍然是不稳定的.

违反volatile语义的唯一方法是通过sun.misc.Unsafe API.

点赞