Pregunta Concurrencia de Java: CAS vs Locking [cerrado]


Estoy leyendo el libro Concurrencia de Java en la práctica. En el capítulo 15, están hablando de los algoritmos no bloqueantes y comparar y cambiar (CAS) método.

Está escrito que CAS funciona mucho mejor que los métodos de bloqueo. Quiero preguntarle a las personas que ya trabajaron con estos dos conceptos y me gustaría saber cuándo está prefiriendo cuál de estos conceptos? ¿Es realmente mucho más rápido?

Para mí, el uso de cerraduras es mucho más claro y más fácil de entender, y tal vez incluso mejor para mantener (Por favor, corríjame si estoy equivocado). ¿Deberíamos centrarnos realmente en crear nuestro código simultáneo relacionado con CAS que bloqueos para obtener un mejor impulso de rendimiento o la sostenibilidad es más importante?

Sé que tal vez no haya una regla estricta sobre cuándo usar qué. Pero me gustaría escuchar algunas opiniones, experiencias con el nuevo concepto de CAS.


65
2018-04-18 22:07


origen


Respuestas:


El CAS generalmente es mucho más rápido que el bloqueo, pero depende del grado de contención. Debido a que CAS puede forzar un reintento si el valor cambia entre leer y comparar, un hilo teóricamente puede atascarse en una espera ocupada si la variable en cuestión está siendo golpeada duramente por muchos otros hilos (o si es costoso calcular un nuevo valor) del valor anterior (o ambos)).

El problema principal con CAS es que es mucho más difícil programar con el bloqueo correctamente. Eso sí, bloquear es, a su vez, mucho más difícil de usar correctamente que el envío de mensajes o STM, por lo tanto, no tome esto como un endoso resonante para el uso de cerraduras.


38
2018-04-18 22:22



La velocidad relativa de las operaciones es, en gran medida, un problema. Lo que es relevante es la diferencia en la escalabilidad entre algoritmos basados ​​en bloqueo y no bloqueo. Y si está ejecutando un sistema central de 1 o 2, deje de pensar en esas cosas.

Los algoritmos sin bloqueo generalmente escalan mejor porque tienen "secciones críticas" más cortas que los algoritmos basados ​​en bloqueo.


25
2018-04-29 00:01



Puedes mirar los números entre un ConcurrentLinkedQueue y un BlockingQueue. Lo que verás es que CAS es notablemente más rápido en contención de hilos moderada (más realista en aplicaciones del mundo real).

La propiedad más atractiva de no bloqueo Algoritmos es el hecho de que si falla un hilo (falta de caché, o peor, falla de seg), otros hilos no notarán esta falla y podrán continuar. Sin embargo, cuando se adquiere un bloqueo, si el hilo que contiene el bloqueo tiene algún tipo de falla del sistema operativo, cada hebra que espere a que se libere el bloqueo también será golpeada con el fallo.

Para responder a sus preguntas, sí, algoritmos o colecciones sin bloqueo de subprocesosConcurrentLinkedQueue, ConcurrentSkipListMap/Set) puede ser significativamente más rápido que sus contrapartes de bloqueo. Sin embargo, como señaló Marcelo, corregir los algoritmos que no bloquean es muy difícil y requiere mucha consideración.

Deberías leer sobre el Michael y Scott Queue, esta es la implementación de cola para ConcurrentLinkedQueue y explica cómo manejar una función atómica bidireccional y segura para hilos con un solo CAS.


18
2018-04-18 23:00



Hay un buen libro relacionado con el tema de la concurrencia sin bloqueos: "El arte de la programación multiprocesador" de Maurice Herlihy


12
2018-04-22 10:15



Si está buscando una comparación del mundo real, aquí hay una. Nuestra aplicación tiene dos (2) subprocesos 1) Un hilo de lectura para la captura de paquetes de red y 2) un hilo de consumidor que toma el paquete, lo cuenta e informa las estadísticas.

El subproceso n. ° 1 intercambia un solo paquete a la vez con el subproceso n. ° 2

Resultado n. ° 1 - usa un intercambio personalizado basado en CAS usando los mismos principios que SynchronousQueue, donde se llama nuestra clase CASSynchronousQueue:

30,766,538 packets in 59.999 seconds ::  500.763Kpps, 1.115Gbps 0 drops
libpcap statistics: recv=61,251,128, drop=0(0.0%), ifdrop=0

Resultado n. ° 2 - cuando reemplazamos nuestra implementación CAS con el estándar java SynchronousQueue:

8,782,647 packets in 59.999 seconds ::  142.950Kpps, 324.957Mbps 0 drops 
libpcap statistics: recv=69,955,666, drop=52,369,516(74.9%), ifdrop=0

No creo que la diferencia en el rendimiento no pueda ser más clara.


7
2017-07-20 03:12