Buscar..


Observaciones

La clase Unsafe permite que un programa haga cosas que no están permitidas por el compilador de Java. Los programas normales deben evitar el uso Unsafe .

ADVERTENCIAS

  1. Si comete un error al utilizar las API no Unsafe , es probable que sus aplicaciones causen que la JVM se bloquee y / o muestre síntomas que son difíciles de diagnosticar.

  2. La API Unsafe está sujeta a cambios sin previo aviso. Si lo usa en su código, es posible que deba volver a escribir el código al cambiar las versiones de Java.

Instalar sun.misc.Unsafe a través de la reflexión

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 tiene un constructor privado, y el getUnsafe() estático getUnsafe() con una comprobación del cargador de clases para garantizar que el código se haya cargado con el cargador de clases principal. Por lo tanto, un método para cargar la instancia es usar la reflexión para obtener el campo estático.

Creación de una instancia de sun.misc.Unsafe a través de bootclasspath

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

Si bien este ejemplo se compilará, es probable que falle en tiempo de ejecución a menos que la clase Insegura se haya cargado con el cargador de clases primario. Para asegurarse de que esto suceda, la JVM debe cargarse con los argumentos apropiados, como:

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

La clase foo.bar.MyApp puede usar UnsafeLoader.loadUnsafe() .

Obtención de instancia de inseguro

Inseguro se almacena como un campo privado al que no se puede acceder directamente. El constructor es privado y el único método para acceder a public static Unsafe getUnsafe() tiene acceso privilegiado. Mediante el uso de la reflexión, hay una solución alternativa para que los campos privados sean accesibles:

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

Usos de inseguros

Algunos usos de inseguros son los siguientes:

Utilizar API
Asignación, reasignación y desasignación fuera de almacenamiento / memoria directa allocateMemory(bytes) , reallocateMemory(address, bytes) y freeMemory(address)
Vallas de memoria loadFence() , storeFence() , fullFence()
Hilo de corriente de estacionamiento park(isAbsolute, time) , unpark(thread)
Campo directo y / o acceso a memoria. get* y put* familia de métodos.
Lanzar excepciones sin marcar throwException(e)
CAS y operaciones atómicas Familia de métodos compareAndSwap*
Configuración de la memoria setMemory
Operaciones volátiles o concurrentes. get*Volatile , put*Volatile , putOrdered*

La familia de métodos get y put son relativos a un objeto dado. Si el objeto es nulo, se trata como una dirección absoluta.

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

Algunos métodos solo se definen para int y longs. Puedes usar estos métodos en flotantes y dobles usando floatToRawIntBits , intBitsToFloat, doubleToRawLongBits , longBitsToDouble`



Modified text is an extract of the original Stack Overflow Documentation
Licenciado bajo CC BY-SA 3.0
No afiliado a Stack Overflow