java - thread - ¿Cómo puede weakCompareAndSet fallar falsamente si se implementa exactamente como compareAndSet?
thread java definicion (2)
Hay una diferencia entre la implementación y la especificación ...
Mientras que en una implementación particular no tiene mucho sentido proporcionar diferentes implementaciones, quizás las implementaciones futuras en hardware diferente lo deseen. Si este método tiene su peso en la API es discutible.
Además, los métodos weak
no tienen lugar , antes de ordenar definido. Las versiones no weak
comportan como campos volatile
.
(tenga en cuenta que esta pregunta no es sobre CAS, sino sobre el Javadoc "Puede fallar falsamente" ).
La única diferencia en el Javadoc entre estos dos métodos de la clase AtomicInteger
es que el weakCompareAndSet contiene el comentario: "Puede fallar falsamente" .
Ahora, a menos que mis ojos sean engañados por algún hechizo, ambos métodos parecen estar haciendo exactamente lo mismo:
public final boolean compareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
/* ...
* May fail spuriously.
*/
public final boolean weakCompareAndSet(int expect, int update) {
return unsafe.compareAndSwapInt(this, valueOffset, expect, update);
}
Entonces me doy cuenta de que "May" no significa "Must", pero entonces ¿por qué no todos comenzamos a agregar esto a nuestra base de código?
public void doIt() {
a();
}
/**
* May fail spuriously
*/
public void weakDoIt() {
a();
}
Estoy realmente confundido con ese weakCompareAndSet () que parece hacer lo mismo que compareAndSet () pero que "puede fallar falsamente" mientras que el otro no puede.
Aparentemente, el "débil" y el "fallo espurio" están relacionados de alguna manera con el orden "sucede antes" pero todavía estoy muy confundido por estos dos métodos AtomicInteger (y AtomicLong etc.): porque aparentemente llaman exactamente el mismo inseguro Método .compareAndSwapInt .
Estoy particularmente confundido porque AtomicInteger
se introdujo en Java 1.5, por lo tanto después de que el Modelo de Memoria Java cambia (por lo que obviamente no es algo que podría "fallar falsamente en 1.4" pero cuyo comportamiento cambió a "no fallará falsamente en 1.5" ) .
Solo para jugar un poco, si tu pregunta fuera
¿Cómo puede fallar débilmente fallar si se implementa exactamente como DoIt?
¡Aquí está la respuesta!
public void doIt() {
a();
}
/**
* May fail spuriously
*/
public void weakDoIt() {
a();
}
void a(){
if(Thread.currentThread().getStackTrace()[2].toString().contains("weakDoIt"))
System.out.println("I will fail spuriously!");
else System.out.println("I won''t fail spuriously!");
}