Unsafe es la piedra angular de la operación sin bloqueo de Java, y son indispensables en clases de concurrencia sin bloqueo. Por ejemplo, concurrenthashmap y concurrentlinkedqueue son implementados por la clase insegura. En comparación con las cerraduras en Java, básicamente no tiene sobrecarga y esperará en su lugar. Este artículo presenta principalmente las operaciones principales en inseguros.
1 comparación
/*** Compare el valor en la ubicación de memoria en el desplazamiento de OBJ y el valor esperado, y actualice si es lo mismo. Esta actualización no es interrumpible. ** @param obj objeto que debe actualizarse* @param compensación el desplazamiento del campo entero en obj* @param espera el valor que se espera en el campo* @param actualización de la actualización Si el valor esperado se espera es el mismo que el valor actual del campo, establece el valor de este nuevo valor* @retret, el valor del campo se cambia, regresa verdadero*/público boolean booleanwapin actualizar);
Esta es la famosa operación CAS, que se divide en tres pasos.
La familia CAS también incluye comparación en comparación con comparación (), comparación.
Use un ejemplo clásico de AtomicInteger para ilustrar:
Public final int getAndadd (int delta) {return unsafe.getAndAdDint (this, valueOffset, delta);} // unsafe.getandaddintpublic final int getAndaddint (objeto var1, long var2, int var4) {int var 5; do { / ** Obtenga el valor original* / var5 = this.getIntVolatile (var1, var2); / ** Confirme que el valor original no ha sido modificado por otros subprocesos, luego realice la operación de actualización VAR5 + VAR4*/} while (! This.compareAndsWapint (var1, var2, var5, var5 + var4)); return var5;}2 putorder
/**** Establece el valor del campo entero en el desplazamiento especificado en el objeto* suministrado al valor dado. Esta es una versión ordenada o perezosa * de <code> PutIntVolatile (Object, Long, Int) </code>, que * no garantiza la visibilidad inmediata del cambio a otros hilos *. Solo es realmente útil donde el campo entero es * <code> volátil </code>, y por lo tanto se espera que cambie inesperadamente. * * @param obj El objeto que contiene el campo para modificar. * @param offset el desplazamiento del campo entero dentro de <code> obj </code>. * @param Valor El nuevo valor del campo. * @see #putIntVolatile (objeto, largo, int) */ public nation void putorderedInt (object obj, largo desplazamiento, int value);
Modifique la posición donde el desplazamiento del objeto OBJ se compensa con el valor, porque no hay operación de memoria en Java, y esta operación de inseguro suplementa la operación de memoria insuficiente. También se puede utilizar para operaciones de matriz, como concurrenthashmap para una gran cantidad de uso
Segmento <k, v> s0 = nuevo segmento <k, v> (loadFactor, (int) (cap * loadFactor), (hashentry <k, v> []) new Hashentry [Cap]); Segmento <k, v> [] ss = (segmento <k, v> []) nuevo segmento [ssize]; // Escribir S0 a la posición donde la matriz se suscrita a 0: SS [0] = S0 Unsafe.putOrderDoBject (SS, SBase, S0); // Escritura ordenada de segmentos [0]
Cabe señalar que OBJ debe establecerse en Volátil, de lo contrario será invisible para otros hilos.
3 putxxxvolatil
/**** Establece el valor del campo entero en el desplazamiento especificado en el objeto* suministrado al valor dado, con semántica de almacén volátil. * * @param obj El objeto que contiene el campo para modificar. * @param offset el desplazamiento del campo entero dentro de <code> obj </code>. * @param Valor El nuevo valor del campo. */ public nation void putIntvolatile (obj obj, offset largo, valor int);
Se siente lo mismo que PutorderInt, porque debe estar configurado para volátil, de lo contrario, ¿cuál es el uso?
Lo anterior son todos los puntos de conocimiento que compartí contigo esta vez. Gracias por su apoyo a Wulin.com.