2008-12-10 11 views

Respuesta

6

Significa que puede devolver falso (y no establecerá el nuevo valor), incluso si actualmente contiene el valor esperado.

En otras palabras, el método puede no hacer nada y volver falsa sin razón aparente ...
Hay arquitecturas de CPU que esto puede tener una ventaja de rendimiento sobre una fuerte CompareAndSet().


Un poco más de detalles concretos sobre por qué algo así podría suceder.

Algunas arquitecturas (como las ARM más nuevas) implementan operaciones CAS utilizando un conjunto de instrucciones Load Linked (LL)/Store Conditional (SC). La instrucción LL carga el valor en una ubicación de memoria y 'recuerda' la dirección en alguna parte. La instrucción SC almacena un valor en esa ubicación de memoria si el valor en la dirección recordada no se ha modificado. Es posible que el hardware para creer que la situación se ha modificado, aunque al parecer no tiene un número de posibles razones (y las razones podría variar según la arquitectura de CPU):

  1. la ubicación puede haber sido escrito con el mismo valor
  2. la resolución de las direcciones observadas podría no ser exactamente la ubicación de la memoria de interés (líneas de memoria). Una escritura en otra ubicación que está "cerca" puede hacer que el hardware marque la dirección en cuestión como "sucia"
  3. varias otras razones que pueden hacer que la CPU pierda el estado guardado de la instrucción LL - interruptores de contexto , cambios de caché o cambios en la tabla de páginas, tal vez.
18

falsamente: sin razón aparente

Según atomic javadoc paquete:

Las clases atómicas también apoyan método weakCompareAndSet, que ha aplicabilidad limitada.

En algunas plataformas, la versión débil puede ser más eficiente que compareAndSet en el caso normal, pero difiere en que cualquier invocación dada del método weakCompareAndSet puede devolver false falsamente (es decir, sin razón aparente).

Un retorno falso significa solo que la operación puede reintentarse si se desea, confiando en la garantía de que la invocación repetida cuando la variable contiene expectedValue y que ningún otro hilo intenta establecer la variable finalmente tendrá éxito.
(Tales fallas espúreas pueden deberse, por ejemplo, a los efectos de contención de memoria que no están relacionados con si los valores esperados y actuales son iguales.)

Además, weakCompareAndSet no proporciona garantías de pedido que generalmente se necesitan para el control de sincronización.


Según this thread, no es tanto por el "hardware/OS", pero debido a que el algoritmo subyacente utilizado por weakCompareAndSet:

weakCompareAndSet establece atómicamente el valor de la dado el valor actualizado si el valor actual == el valor esperado. Puede fallar falsamente.

A diferencia compareAndSet(), y otras operaciones en una AtomicX, la operación weakCompareAndSet() no crea ningún happens-before orderings.

Por lo tanto, el hecho de que un hilo vea una actualización de un AtomicX causada por un weakCompareAndSet no significa que esté sincronizado correctamente con operaciones que ocurrieron antes del weakCompareAndSet().

Probablemente no desee utilizar este método, sino que simplemente use compareAndSet; ya que hay pocos casos en que weakCompareAndSet sea más rápido que compare y establece, y hay una serie de casos en los que tratar de optimizar su código utilizando weakCompareAndSet en lugar de compareAndSet introducirá errores de sincronización sutiles y difíciles de reproducir en su código.


nota que se refiere happens-before orderings:

el modelo de memoria de Java (JMM) define las condiciones bajo las cuales se garantiza un hilo de leer una variable para ver los resultados de una escritura en otro hilo .

El JMM define un orden en las operaciones de un programa llamado happens-before.

Ocurre antes: los pedidos entre subprocesos solo se crean sincronizando en un bloqueo común o accediendo a una variable volátil común.

En ausencia de un orden de suceder antes de, la plataforma Java tiene gran libertad para retrasar o cambiar el orden en que las escrituras en un hilo se vuelven visibles para las lecturas de esa misma variable en otro.

0

¿Pero por qué se permite que ocurra esto en absoluto? ¿Esto es porque el hardware/sistema operativo subyacente tiene errores? ¿O hay alguna buena razón técnica detrás de esto?

+0

Acabo de agregar el motivo técnico, relacionado con el orden de "happen-before" en el JMM (Java Memory Model) – VonC

6

Un buen caso de uso para weakCompareAndSet son los contadores de rendimiento: no hay necesidad de pedir, alta tasa de actualizaciones (por lo que el pedido duele en sistemas débilmente ordenados), pero no elimina conteos bajo cargas altas (contadores perf-contentos pueden dejar caer 99% de todos los conteos, esencialmente dejando el valor de los contadores en relación con los contadores no contendientes al azar).