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

关于java - 反射会保持java中volatile的语义吗,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36232847/

10-14 11:53