CAS funcionamiento y el principio de la implementación en Java

1. ¿Qué es el CAS?

CAS: Comparar y Swap, traducida para comparar e intercambio.

Ver esta definición, podemos decir sin ningún sentido de la palabra, pero la palabra que mejor sabe resumió el proceso de las operaciones CAS.

operación CAS incluye tres operandos - una posición de memoria (V), se espera que el valor original (A) y el nuevo valor (B). Si la posición de memoria del valor original coincide con el valor esperado, entonces el procesador se actualizará automáticamente el valor de ubicación para el nuevo valor. De lo contrario, el procesador no hace nada. En cualquier caso, se devuelve el valor de la posición antes de la instrucción CAS. (. En algunos casos especiales será devuelto sólo si CAS CAS es exitosa, sin necesidad de extraer el valor actual) CAS explica de manera efectiva, "Creo que la ubicación debe contener el valor V A; Si se incluye este valor, la opción de venta B en esta posición; de lo contrario, no cambie la ubicación, sólo dime el valor de esta ubicación puede ahora ".

La siguiente este código JAVA, básicamente refleja la operación del proceso CAS. Nótese, sin embargo, las operaciones de bienes CAS son realizadas por la CPU, la CPU garantizar un funcionamiento atomicidad, la función está lejos de CAS código Java que se puede realizar (veremos el código de montaje CAS).

	/**
	* 假设这段代码是原子性的,那么CAS其实就是这样一个过程
	*/
	public boolean compareAndSwap(int v,int a,int b) {
		if (v == a) {
			v = b;
			return true;
		}else {
			return false;
		}
	}

CAS manera generalmente sincronizada para V lee de valor de la dirección A, el cálculo de múltiples pasos realiza para obtener un nuevo valor de B, entonces el valor de V CAS de A a B. Si el valor de V no se ha cambiado al mismo tiempo, la operación se ha realizado correctamente CAS.

Estas palabras significan, operación CAS puede evitar que la memoria variable compartida aparece sucia sucia problema de lectura y escritura, el problema de la CPU multi-núcleo a menudo en el caso de multi-hilo, por lo general utilizamos cerraduras para evitar este problema, pero para evitar la operación del CAS multi-hilo contención de bloqueo, cambio de contexto, y la programación de proceso.

Al igual que en la instrucción CAS permite que el algoritmo para realizar una lectura - modificar - las operaciones de escritura, sin temor a otros hilos modificar las variables, ya que si otro hilo para modificar las variables, CAS lo detectará (y fracasado), el algoritmo puede calcular de nuevo la operación.

CAS operaciones en la realización del principio de 2.JAVA

CAS llamando a la implementación del código JNI. JNI: Java Native Interface para las llamadas locales Java, Java permite llamar a otros idiomas.

En la clase de compareAndSwapInt inseguro () método es un ejemplo, compareAndSwapInt es C y de montaje medios de código para lograr.
El siguiente a partir del análisis de la CPU más común (x86 de Intel) para explicar la realización del principio de CAS.
A continuación se muestra el código fuente en clases sun.misc.Unsafe compareAndSwapInt JDK () Método:

// native方法,是没有其Java代码实现的,而是需要依靠JDK和JVM的实现
public final native boolean compareAndSwapInt(Object o, long offset,
                                              int expected,
                                              int x);

Podemos ver que este es un método local. código C ++ para este OpenJDK enfoque local en las llamadas a su vez para: unsafe.cpp, atomic.cpp y atomicwindowsx86.inline.hpp. En última instancia, el método nativo en una posición de OpenJDK: OpenJDK-7-FCS-src-b147-27jun2011 \ OpenJDK \ hotspot \ src \ oscpu \ windowsx86 \ vm \ atomicwindowsx86.inline.hpp (correspondiente a las ventanas del sistema operativo, la instrucción X86 set). A continuación se muestra el fragmento de código fuente correspondiente al procesador Intel x86:

// Adding a lock prefix to an instruction on MP machine
// VC++ doesn't like the lock prefix to be on a single line
// so we can't insert a label after the lock prefix.
// By emitting a lock prefix, we can define a label after it.
#define LOCK_IF_MP(mp) __asm cmp mp, 0  \
                       __asm je L0      \
                       __asm _emit 0xF0 \
                       __asm L0:

inline jint Atomic::cmpxchg (jint exchange_value, volatile jint* dest, jint compare_value) 
{
  // alternative for InterlockedCompareExchange
  int mp = os::is_MP();
  __asm {
    mov edx, dest
    mov ecx, exchange_value
    mov eax, compare_value
    LOCK_IF_MP(mp)               // 这里需要先进行判断是否为多核处理器
    cmpxchg dword ptr [edx], ecx // 如果是多核处理器就会在这行指令前加Lock标记
  }
}

OS :: is_MP () Devuelve el actual JVM se está ejecutando en la máquina si la CPU de varios núcleos, por supuesto, volver 1 para verdadero, 0 para falso

Seguido de un período de ensamblador, C / C ++ en línea conjunto de soporte, sabemos que esta característica es como, voy a explicar esto en la compilación llanura del significado general.

  __asm {
    mov edx, dest             # 取Atomic::cmpxchg方法的参数dest内存地址存入寄存器edx
    mov ecx, exchange_value   # 取Atomic::cmpxchg方法的参数exchange_value内存地址存入寄存器ecx
    mov eax, compare_value    # 取Atomic::cmpxchg方法的参数compare_value内存地存入寄存器eax
    LOCK_IF_MP(mp)            # 如果是多核处理器,就在下一行汇编代码前加上lock前缀
    cmpxchg dword ptr [edx], ecx # 比较ecx和eax的中内存地址的中存的变量值,如果相等就写入edx内存地址中,否则不
  }

la instrucción ensamblador x86 cmpxchg sí garantiza la atomicidad, de hecho, es la realización de operaciones CAS CPU, así que la pregunta es, ¿por qué garantizar la atomicidad también hay que añadir el prefijo de bloqueo en el procesador multi-núcleo en ella?

La respuesta es: procesadores de múltiples núcleos no pueden garantizar la visibilidad, el prefijo de bloqueo puede garantizar la visibilidad de esta línea recopilación de todos los valores, la causa de este problema es causado por la caché de CPU multi-core (culpable x86 es la presencia en la memoria intermedia de almacenamiento).
Dicha protección por los procesadores de múltiples núcleos visibilidad prefijo de bloqueo, entonces la CPU para completar la operación por cmpxchg CAS problema perfecta instrucción atómica!
Decir una cosa más, esto es sólo en x86 implementaciones para otras plataformas, hay diferentes maneras de lograr esta esperanza de que los lectores deben ser claras.
Esta lectura código ensamblador no importa, pero el efecto que el mecanismo de bloqueo utiliza la CPU para asegurar que todo el CAS operación atómica. operación atómica atómica sobre el mecanismo de bloqueo operación --cpu y la CPU en la CPU.

paquete de aplicación 3.concurrent CAS

Dado que el CAS java tiene tanto la semántica de memoria de lectura-escritura volátiles y volátiles, la comunicación entre las hebras Java ahora tienen las cuatro formas siguientes:
. 1, enhebrar una escritura variables de volátiles, a continuación, el hilo B lee las variables volátiles.
2, una variable volátil hilo de escritura, a continuación, actualizar B CAS este hilo con variables volátiles.
3, un hilo con un volátiles actualizaciones variable de CAS, a continuación, actualiza el hilo B con variables volátiles CAS.
4, A rosca con un volátiles actualizaciones variable de CAS, a continuación, el subproceso B lee las variables volátiles.

Nota: la palabra clave volátil para asegurar la visibilidad de las variables, en función del modelo de memoria de Java, cada hilo tiene su propia memoria de pila, las variables de memoria de pila en diferentes hilos es posible debido a las diferentes operaciones dentro de la pila, mientras la CPU está directamente datos de la pila manipulación y almacena en su memoria caché, por lo que la aparición de la CPU multi-core gran problema, y ​​que las variables volátiles aseguran que cada núcleo de la CPU y la memoria caché no van a leer datos de la memoria de pila, sino directamente leer datos de la memoria del montón, y escribe directamente vuelto a escribir en el montón de memoria, asegurando así la visibilidad y el orden entre las variables locales compartidos multi-hilo (pero no garantiza la atomicidad), en la volátil - la programación concurrente de Java: volátiles análisis de palabras clave

el funcionamiento de Java del CAS se puede implementar en un moderno CPU a nivel de hardware instrucciones atómicas (JVM en lugar de confiar en el sistema operativo o el mecanismo de bloqueo), mientras que la palabra clave volátil y asegura la visibilidad y las instrucciones en el orden de las variables compartidas entre los hilos, por lo que en virtud de este dos medios, se pueden lograr sin depender de que el sistema operativo para lograr un mecanismo de bloqueo para asegurar la consistencia de las variables compartidas concurrentes.

Si analizamos detenidamente la implementación de paquetes concurrente código fuente, se encuentra un modo de realización común:
En primer lugar, las variables de declarar compartida a ser volátiles;
a continuación, el uso de condiciones de actualización CAS atómicas para lograr la sincronización entre hilos;
al mismo tiempo, cooperar a la volatilidad de lectura / escritura y leer y escribir CAS tiene la semántica de memoria volátil para la comunicación entre los hilos.

Aquí Insertar imagen Descripción

Publicados 451 artículos originales · ganado elogios 17 · Vistas a 10000 +

Supongo que te gusta

Origin blog.csdn.net/zt2650693774/article/details/105038214
Recomendado
Clasificación