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