Prefacio

  Calvo sólo puede llegar a ser fuertes

  Before''ve demasiados artículos relacionados hilos escritos, los estudiantes interesados pueden ir a averiguar:

  https: // github.com / ZhongFuCheng3y / 3y / blob / master / src / hilo.Maryland

  

  En la lectura de "Manual de Ali Baba Desarrollo de Java" rese?a del libro, así como cuestiones sin resolver:

  Si sí cuentan ++ operación, implementado usando las siguientes categorías: AtomicInteger recuento = new AtomicInteger (); recuento.addAndGet (1); si JDK8, LongAdder recomendada rendimiento orientada a objetos AtomicLong mejor que (bloqueo optimista a reducir el número de reintentos).

  Antes de aprender cuando la clase AtomicInteger han visto muchas veces, no me han hecho notas relacionadas.Cuando nos encontramos con un problema, por lo que llegó a escribir notas y queremos deshacernos del problema en el proceso de aprendizaje.

  En primer lugar, las bases básica

  En primer lugar, tomamos un ejemplo:

  AtomicMain public class {

  public estático void Main (args String []) {lanza InterruptedException

  Servicio ExecutorService = Ejecutores.newCachedThreadPool ();

  Conde contar = count nuevo ();

  // 100 hilos a variables compartidas más 1

  for (int i = 0; i < 100; i++) {

  Servicio.ejecutar (() -> recuento.Incrementar ());

  }

  // espera para la ejecución de la rosca se ha mencionado anteriormente

  Servicio.apagar ();

  Servicio.awaitTermination (1, TimeUnit.DIAS);

  Sistema.fuera.println ( "Público número: Java3y ---------");

  Sistema.fuera.println (recuento.getCount ());

  }

  }

  Contador de la clase {

  // variable compartida

  recuento de enteros privada = 0;

  pública Entero getCount () {

  recuento de retorno;

  }

  aumento public void () {

  contar ++;

  }

  }

  Adivinar el resultado es el número?Es 100?

  Ejecutar varias veces más que se puede encontrar: el resultado es incierto, puede ser 95, 98 que podría ser, podría ser 100

  

  Con base en los resultados que conocemos: el código anterior no es seguro para subprocesos!Si el código de flujos seguros, los resultados de múltiples ejecuciones es consistente!

  Podemos encontrar el problema: no es una operación atómica.Debido a la necesidad de ir a través de tres pasos.por ejemplo:

  Si un determinado momento: Un valor de densidad de hilos se lee 10, el hilo B lee el valor de recuento es 10

  A en el hilo, cuando el valor de cómputo 11

  B en la rosca, cuando el valor de recuento es 11 (debido a que el número de hilos se lee B 10)

  Así que aquí usted debe saber qué nuestros resultados son inciertos de ella.

  Para el código anterior se convierte en un hilo de seguridad (cada vez que el resultado es 100), también es muy simple, después de todo, aprendimos sincronizados personas de bloqueo:

  Además sincronizado bien sólo cerradura

  aumento vacío sincronizada pública () {

  contar ++;

  }

  No importa cuántas veces que debe realizarse, somos atraídos 100:

  

  También se puede encontrar en el código anterior, solamente una simple operación, han utilizado el bloqueo sincronizado, un poco demasiado hecha.

  cerradura sincronizada es exclusivo, lo que significa que si hay otros hilos en la ejecución del hilo actual puede esperar!

  Así que tipo de variables atómicas en el debut!

  1.Echemos un vistazo a 2CAS

  Antes de escribir el artículo, pensé que hay una cierta comprensión de la CAS (como conceptos vistos anteriormente, creyó entender).Sin embargo, el teclado real superó el momento de escribir, todavía no está completamente entendido encontró.Así que ahora vamos a ver CAS.

  Fuente Wikipedia:

  Compara y de intercambio (swap de comparar y, CAS), es una operación atómica, puede ser utilizado para implementar el intercambio de datos sin interrupción en la operación de programación multihilo, evitando así multihilo simultáneo reescrito porque el orden de ejecución de datos no es una datos, así como la imprevisibilidad de inconsistencias interrupciones generadas. La operación especificado por el valor de los datos en la memoria se compara, como será reemplazado cuando el valor en la memoria de datos a un nuevo valor.

  CAS tiene tres operandos:

  valor de la memoria V

  antiguo valor esperado de una

  Para modificar el nuevo valor de B

  Cuando varios subprocesos intentan simultáneamente para utilizar la actualización CAS la misma variable, sólo un hilo puede actualizar el valor de las variables (A y V valores de la misma memoria, el valor de la memoria se modifica V B), mientras que los otros hilos son la insuficiencia durante hilo y no va a ser suspendida, pero se le dijo que la competencia no funciona y puede intentarlo de nuevo (o no hacer nada).

  Dibujamos un diagrama de entenderlo:

  

  CAS podemos encontrar que hay dos casos:

  Si el valor de la memoria V y nuestro valor esperado es igual a A, a continuación, modifique el valor de la memoria es B, la operación se ha realizado correctamente!

  Si el valor de la memoria V A y nuestras expectativas no son iguales, por lo general hay dos casos:

  Reintento (spin)

  hacer nada

  Seguimos a mirar hacia abajo, si nuestro valor de la memoria V y A no es igual al valor esperado, se debe volver a intentar cuando, a qué hora hacer nada.

  1.2.1CAS falló reintentos (spin)

  Por ejemplo, he utilizado el valor de recuento 100 hilo superior de más 1.Todos sabemos que: Si en una situación segura para los subprocesos, el resultado final debe ser el valor de este recuento es 100.Eso significa: Cada hilo en este valor de cómputo incrementando sustancialmente.

  Continúo para dibujar un diagrama para explicar cómo el reintento CAS (ciclo de reintento) de:

  

  El gráfico anterior sólo se simulan dos hilos, pero lo suficiente como para explicar el problema.

  1.2.2CAS no lo hacen nada

  Cada hilo está por encima de 1 para el valor de cómputo será a?adido, pero también puede tener esta situación: el valor de cómputo a 5

  Tengo que dibujar un diagrama para explicar:

  

  CAS es entender el núcleo: CAS es atómica, aunque es posible ver la comparación y luego modificado (comparar y swap) piensan que habrá dos operaciones, pero al final son atómicos!

  En segundo lugar, una breve atómica clases de variables

  clases de variables atómicas en el paquete, en general hay tantos:

  

  Podemos clasificarlos:

  tipo básico:

  AtomicBoolean: Boolean

  AtomicInteger: Entero

  AtomicLong: entero largo

  Formación:

  AtomicIntegerArray: matriz de enteros

  AtomicLongArray: array de entero largo

  AtomicReferenceArray: array de tipos de referencia

  Tipos de referencia:

  tipos de referencia: AtomicReference

  AtomicStampedReference: con referencia al número de versión del tipo de

  AtomicMarkableReference: con referencia al tipo de bandera

  atributos de los objetos:

  AtomicIntegerFieldUpdater: propiedades del objeto es un número entero

  AtomicLongFieldUpdater: propiedades del objeto es un entero largo

  AtomicReferenceFieldUpdater: propiedades de un objeto es un tipo de referencia

  JDK8 nueva DoubleAccumulator, LongAccumulator, DoubleAdder, LongAdder

  Es una mejora sobre otros tipos de AtomicLong.Por ejemplo LongAccumulator con LongAdder bajo ambiente de alta concurrencia más eficiente que AtomicLong.

  clase bolsa atómica se implementan usando básicamente una clase contenedora inseguro.

  dentro peligrosas Existen unos pocos de nuestro método favorito (CAS):

  // parámetros primero y segundo y una dirección que representa una instancia de objeto, el tercer parámetro representa un valor deseado, el valor actualizado de la cuarta parámetro representa

  booleano nativa compareAndSwapObject (var1 objeto, a largo var2, var4 objeto, var5 Objeto) público final;

  compareAndSwapInt pública final nativa booleano (var1 objeto, a largo var2, var4 int, int var5);

  booleano nativa compareAndSwapLong (var1 objeto, a largo var2, var4 larga, larga var6) público final;

  Descripción general En principio es: la gran método inseguro clase de implementación Atómica paquete de llamada, y en realidad llama a código C subyacente en condiciones de riesgo, el código compilado en C para llamar al último genera una cmpxchg una instrucción de la CPU, se completa la operación.Esta es también la razón por CAS es atómica, ya que es una instrucción de la CPU, no será interrumpido.

  2.1 utilizando clases de variables atómicas

  Ya que también se mencionó anteriormente, el uso de la cerradura sincronizada exageración, utilizamos clases de variables atómicas para cambiarlo:

  Contador de la clase {

  // variable compartida (usando AtomicInteger bloqueo vez sincronizada)

  recuento privada AtomicInteger = new AtomicInteger (0);

  pública Entero getCount () {

  recuento de retorno.obtener ();

  }

  aumento public void () {

  count.incrementAndGet ();

  }

  }

  // método principal está todavía por encima

  Modifica, realizar no importa cuántas veces, nuestros resultados serán siempre 100!

  De hecho, el uso de paquetes de clase atómicas no están bajo la mamá Atómica, comprender diversos tipos de clase atómica, echar un vistazo a la API, será básicamente utilizar la (línea también escrito con más detalle, por lo que estoy aquí decisiva perezoso).

  2.problema 2ABA

  Uso CAS tiene la desventaja de ABA es el problema, ?cuál es el problema, entonces ABA?En primer lugar, lo describo en las palabras:

  Ahora tengo una variable, hay tres hilos, a saber, A, B, C

  Un hilo y el recuento de rosca variable C durante la lectura, por lo que el valor de la memoria y el valor esperado de la rosca A y C son ambos 10 hilos

  En este momento, el hilo A CAS se utiliza para modificar el valor de recuento 100

  Después de la modificación, en este momento, el hilo B vino, para dar el valor de cómputo de lectura de 100 (valor esperado y el valor de la memoria es de 100), el valor de cómputo a un 10 modificado

  C hilos de ejecución para obtener el valor correcto se encuentra en la memoria 10, el valor esperado es 10, el valor de recuento se modifica para 11

  Las operaciones anteriores se pueden realizar correctamente ejecutada, por lo que pasará??C Un hilo no puede saber el valor modificado B número de hilos y el hilo, por lo que existe un riesgo.

  Aquí me dibujar un diagrama para ilustrar el problema de ABA (lista enlazada, por ejemplo):

  

  2.3 para resolver el problema de la ABA

  ABA Para resolver el problema, podemos utilizar las clases AtomicStampedReference y AtomicMarkableReference JDK que nos proporcione.

  AtomicStampedReference:

  Un {AtomicStampedReference @code} mantiene una referencealong objeto con un número entero "sello", que puede ser actualizado atómicamente.

  Se trata simplemente de proporcionar para esto en una versión del objeto, y si esta versión se ha modificado, se actualizan automáticamente.

  Principio es, probablemente: el mantenimiento de un objeto pares, pares de almacenamiento de objetos nuestras referencias a objetos y un valor de marca.CAS comparar cada uno de los dos objetos par

  // objeto par

  clase estática privada Par {

  la referencia T final;

  sello int final;

  Par privado (referencia T, sello int) {

  esta.de referencia = referencia;

  esta.estampar = sello;

  }

  static Par de (referencia T, sello int) {

  retorno nuevo par(Referencia, sello);

  }

  }

  Par volátil privada par;

  // comparación está sujeta Pari

  public boolean compareAndSet (V expectedReference,

  V newReference,

  int expectedStamp,

  int newStamp) {

  Par actual = par;

  regreso

  expectedReference actual ==.referencia &&

  expectedStamp actual ==.estampar &&

  ((Corriente NewReference ==.referencia &&

  newStamp actual ==.sello) ||

  casPair (corriente, Par.de (newReference, newStamp)));

  }

  Debido a que más de un número de versión comparar, por lo que no ponemos en duda la existencia de la ABA.

  2.4LongAdder mejor rendimiento que AtomicLong

  Si JDK8, recomendado objetos LongAdder, mejor que el rendimiento AtomicLong (reduciendo el número de reintentos de bloqueo optimista).

  Ir acceso a algún blog y la información sobre el significado es:

  Al utilizar AtomicLong, en un gran número altamente concurrente de hilos para competir al mismo tiempo actualizar las mismas variables atómicas, sino porque sólo un hilo de CAS tendrá éxito, por lo demás hilos continuarán para tratar de giro tratando de operación del CAS, que será un desperdicio de una gran cantidad de CPU recursos.

  Y pueden resumirse en tal una forma LongAdder: núcleo interno se separa en una matriz de valor de datos (la célula), cada acceso de hilo, los recuentos mapeadas a un número de algoritmos de hash, y el resultado final recuento, esta evaluación compara la matriz y acumulativo.

  Se trata simplemente de una pluralidad de valores dispersos, cuando concurrente puede propagar la presión, un rendimiento mejorado.

  Eso es todo por este artículo, quiero ser útil para aprender, espero que usted apoyará guión Inicio.

  Usted también puede estar interesado en el artículo: En los atómicas implementos paquete Java los principios y la aplicación de Java multi-hilo que operan las variables atómicas paquete atómicas y la clase detallada atómica utilizar Java multi-hilo descripción del paquete atómica y la forma de utilizar Java AtomicInteger detalladas clases de concurrencia AtomicReference Java de - átomo _ nodo de poder Escuela de Java terminar AtomicLong clase atómica de Java concurrencia de _ nodo de poder Escuela de Java terminar la concurrencia de Java de AtomicLongFieldUpdater clase atómica _ nodo de potencia de Java Escuela de terminar la concurrencia de Java de AtomicLongArray clase atómica _ nodo de poder Escuela de Java de terminar en Java para AtomicInteger e int operación de prueba valor mínimo de valor en un multiproceso

?Todavía está sincronizada con?Atómica no entiende?

Recommend Article: