2016-03-26 9 views
4

Zum Beispiel, wenn ich ein flüchtiges Feld in einem Thread änderte, würde das JMM garantieren, dass dann der neue Wert für den anderen Thread sichtbar ist.Wird die Reflektion die Semantik von volatile in Java beibehalten

Meine Frage ist, ist dies immer noch der Fall, wenn ich Reflektion verwenden, das Feld zu ändern?

Der folgende Code ist nur ein Beispiel zu zeigen, wie Reflexion arbeitet.

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); 
    } 

} 
+1

Ja, nur mit 'Unsafe' können Sie flüchtige Semantik ändern. –

+1

@PeterLawrey Mit anderen Worten, die 'Unsichere' API kümmert sich nicht darum, ob das Feld durch das flüchtige geändert wird oder nicht. Wenn ich 'putXXVolatile()' 'benutze, bekomme ich flüchtige Semantik-Garantie, wenn ich' putXX() 'verwende, habe ich nichts. Ist das wahr? –

+0

@PeterLawrey Und definiert dies in _The Java Language Specification_ oder _The Java Virtual Machine Specification_? Ich möchte etwas mehr über diese Frage erfahren. –

Antwort

2

aus den Kommentaren Heraus

Ja, Änderungen an ein volatile Feld über Reflexion werden auf andere Themen wie ein Standard-Zugang zu sehen sein. Dies liegt daran, dass die Reflektions-API JVM-Byte-Code generiert, um die Aktionen auszuführen, wodurch der Zugriff auf das Feld selbst immer noch instabil ist.

Die einzige Möglichkeit, die volatile Semantik zu verletzen, ist über die sun.misc.Unsafe API.