2017-04-22 8 views
22

Ich habe neuen Funktionen des Java 9 verbracht einige viel Zeit zu untersuchen, aber ich habe keine nützliche und praktische Beispiele.Korrekter Weg VarHandle in Java 9 zu verwenden?

Betrachten Schnipsel nächsten Code, der eine VarHandle erstellt: nächste

class Counter { 
    int i; 
} 

class VarHandleInAction { 
    static final VarHandle VH_COUNTER_FIELD_I; 

    static { 
     try { 
      VH_COUNTER_FIELD_I = MethodHandles.lookup(). 
       in(Counter.class). 
       findVarHandle(Counter.class, "i", int.class); 
     } catch (Exception e) { 
      // ... 
     } 
    } 
} 

Aber was? Ich meine, wie man diesen variablen Handgriff benutzt? Können Sie irgendwelche realen Beispiele geben? das Feld Offset für den Zugriff auf

public final void lazySet(V newValue) { 
    unsafe.putOrderedObject(this, valueOffset, newValue); 
} 

public final boolean compareAndSet(V expect, V update) { 
    return unsafe.compareAndSwapObject(this, valueOffset, expect, update); 
} 

Hier ist die this Zeiger verwendet wird, zusammen mit einem Feld:

+9

Var Griffe (oder Methode behandelt) sind eher Low-Level-APIs für Methodenaufrufe und Speicheroperationen. Die meisten Leute werden diese APIs nie brauchen. –

Antwort

24

Es zum Beispiel in AtomicReference verwendet wird, wo zuvor in Java 8 wurde sun.misc.Unsafe verwendet. Aber das ist nicht sicher, da dieses Feld jeder long Offset könnte, und man könnte eigentlich etwas ganz anderes zugreifen. es gibt jedoch Leistungsvorteile es auf diese Weise dabei (es die VM erzählt spezialisierte CPU-Instruktionen zum Beispiel verwenden), und aus diesem Grund andere Leute haben sun.misc.Unsafe obwohl es eine interne und unsichere API verwendet.

Teil des Zwecks, für VarHandles ist Operationen in sun.misc.Unsafe mit einem sicheren Äquivalent zu ersetzen. Welches ist in the JEP angegeben:

ein Standardmittel definieren die Äquivalente verschiedener java.util.concurrent.atomic und sun.misc.Unsafe Operationen ...

Tore aufzurufen :

Die folgenden Anforderungen müssen erfüllt Ziele:

  • Sicherheit. Es darf nicht möglich sein, die Java Virtual Machine in einen beschädigten Speicherzustand zu versetzen. Zum Beispiel kann ein Feld eines Objekts kann nur mit Instanzen aktualisiert werden, die gießbare zum Feld-Typ sind, oder ein Array-Element nur in einem Array zugegriffen werden, wenn der Arrayindex innerhalb der Arraygrenzen ist.

  • Integrität. Der Zugriff auf ein Feld eines Objekts folgt den gleichen Zugriffsregeln wie bei Getfield- und Putfield-Byte-Codes zusätzlich zu der Einschränkung, dass ein letztes Feld eines Objekts nicht aktualisiert werden kann. (Hinweis: so die Sicherheit und Integrität Regeln gelten auch für MethodHandles gelten, die Zugang zu einem Feld lesen oder schreiben.)

  • Leistung. Die Leistungsmerkmale müssen gleich sein oder ähnlich wie äquivalente sun.misc.Unsafe Operationen (speziell erzeugten Assembler-Code sollte fast identisch Modulo bestimmte Sicherheitsüberprüfungen sein, die sich nicht weggeklappt).

  • Usability. Die API muss besser sein als die sun.misc.Unsafe API.

So in Java 9 sehen diese Methoden wie folgt aus:

public final void lazySet(V newValue) { 
    VALUE.setRelease(this, newValue); 
} 

public final boolean compareAndSet(V expectedValue, V newValue) { 
    return VALUE.compareAndSet(this, expectedValue, newValue); 
} 

Wo VALUE ist ein VarHandle wie folgt definieren:

private static final VarHandle VALUE; 
static { 
    try { 
     MethodHandles.Lookup l = MethodHandles.lookup(); 
     VALUE = l.findVarHandle(AtomicReference.class, "value", Object.class); 
    } catch (ReflectiveOperationException e) { 
     throw new Error(e); 
    } 
} 
Verwandte Themen