Suche…


Bemerkungen

Mit der Unsafe Klasse kann ein Programm Dinge Unsafe , die der Java-Compiler nicht zulässt. Bei normalen Programmen sollte Unsafe .

WARNUNGEN

  1. Wenn Sie bei der Verwendung der Unsafe API einen Fehler machen, Unsafe Ihre Anwendungen dazu, dass die JVM abstürzt und / oder Symptome aufweist, die schwer zu diagnostizieren sind.

  2. Die Unsafe API kann ohne vorherige Ankündigung geändert werden. Wenn Sie es in Ihrem Code verwenden, müssen Sie den Code möglicherweise ändern, wenn Sie die Java-Version ändern.

Instanziieren von sun.misc.Unsafe durch Reflektion

public static Unsafe getUnsafe() {
    try {
        Field unsafe = Unsafe.class.getDeclaredField("theUnsafe");
        unsafe.setAccessible(true);
        return (Unsafe) unsafe.get(null);
    } catch (IllegalAccessException e) {
        // Handle
    } catch (IllegalArgumentException e) {
        // Handle
    } catch (NoSuchFieldException e) {
        // Handle
    } catch (SecurityException e) {
        // Handle
    }
}

sun.misc.Unsafe verfügt über einen privaten Konstruktor, und die statische Methode getUnsafe() wird durch eine Überprüfung des Klassenladers überwacht, um sicherzustellen, dass der Code mit dem primären Klassenlader geladen wurde. Daher besteht eine Methode zum Laden der Instanz darin, das statische Feld mithilfe von Reflektion zu erhalten.

Sun.misc.Unsafe über den Bootclasspath instanziieren

public class UnsafeLoader {
    public static Unsafe loadUnsafe() {
        return Unsafe.getUnsafe();
    }
}

Während dieses Beispiel kompiliert wird, schlägt es wahrscheinlich zur Laufzeit fehl, wenn die Unsafe-Klasse nicht mit dem primären Classloader geladen wurde. Um sicherzustellen, dass dies geschieht, sollte die JVM mit den entsprechenden Argumenten geladen werden, z.

java -Xbootclasspath:$JAVA_HOME/jre/lib/rt.jar:./UnsafeLoader.jar foo.bar.MyApp

Die Klasse foo.bar.MyApp kann dann UnsafeLoader.loadUnsafe() .

Instanz von unsicher erhalten

Unsafe wird als privates Feld gespeichert, auf das nicht direkt zugegriffen werden kann. Der Konstruktor ist privat und die einzige Methode für den Zugriff auf public static Unsafe getUnsafe() hat privilegierten Zugriff. Mithilfe von Reflektionen wird eine Problemumgehung durchgeführt, um private Felder zugänglich zu machen:

public static final Unsafe UNSAFE;

static {
    Unsafe unsafe = null;

    try {
        final PrivilegedExceptionAction<Unsafe> action = () -> {
            final Field f = Unsafe.class.getDeclaredField("theUnsafe");
            f.setAccessible(true);

            return (Unsafe) f.get(null);
        };

        unsafe = AccessController.doPrivileged(action);
    } catch (final Throwable t) {
        throw new RuntimeException("Exception accessing Unsafe", t);
    }

    UNSAFE = unsafe;
}

Verwendung von unsicher

Einige Verwendungen von unsicher ist s:

Benutzen API
Off-Heap / Direct-Speicherzuweisung, Neuzuweisung und Freigabe allocateMemory(bytes) , reallocateMemory(address, bytes) und freeMemory(address)
Gedächtniszäune loadFence() , storeFence() , fullFence()
Parkstrom-Thread park(isAbsolute, time) , unpark(thread)
Direkter Feld- und / oder Speicherzugriff get* und put* Methodenfamilie
Ungeprüfte Ausnahmen werfen throwException(e)
CAS und Atomic Operations compareAndSwap* Methodenfamilie
Speicher einrichten setMemory
Flüchtige oder gleichzeitige Operationen putOrdered* get*Volatile , put*Volatile , putOrdered*

Die Methoden von get und put sind relativ zu einem gegebenen Objekt. Wenn das Objekt null ist, wird es als absolute Adresse behandelt.

// Putting a value to a field
protected static long fieldOffset = UNSAFE.objectFieldOffset(getClass().getField("theField"));
UNSAFE.putLong(this, fieldOffset , newValue);

// Puting an absolute value
 UNSAFE.putLong(null, address, newValue);
 UNSAFE.putLong(address, newValue);

Einige Methoden sind nur für int und longs definiert. Sie können diese Methoden für Floats und Doubles verwenden, indem Sie floatToRawIntBits , intBitsToFloat, doubleToRawLongBits , longBitsToDouble` verwenden



Modified text is an extract of the original Stack Overflow Documentation
Lizenziert unter CC BY-SA 3.0
Nicht angeschlossen an Stack Overflow