Tengo que escribir una prueba de unidad que provoca una condición de carrera para poder probar si probablemente solucioné el problema más adelante. El problema es que la condición de carrera solo ocurre muy raramente, tal vez porque mi computadora tiene solo dos núcleos.Provocar una condición de carrera en Java
El código es algo como lo siguiente:
class MyDateTime {
String getColonTime() {
// datetime is some kind of lazy caching variable declared somewhere(does not matter)
if (datetime == null) {
initDateTime(); //Uses lazy to initlialize variable, takes some time
}
// Colon time stores hh:mm as string
if (datetime.colonTime == null) {
StringBuilder sb = new StringBuilder();
//Now do some steps to build the hh:mm string
//...
//set colon time
datetime.colonTime = sb.toString();
}
return datetime.colonTime;
}
}
Explicación: initDateTime asigna una nueva instancia de fecha y hora, para ello, datetime.colonTime es nulo después (ya que queremos inicializarlo perezoso, como indiqué antes de). Ahora, si el subproceso A ingresa al método y luego el programador lo detiene justo antes de que pueda ejecutar initDateTime(). El subproceso B ahora runst getColonTime(), ve que datetime sigue siendo nulo y lo inicializa. datetime.colonTime es nulo, por lo tanto, el segundo bloque if se ejecuta y datetime.colonTime obtiene el valor de StringBuilder. Si el programador detiene el hilo entre esta línea y la declaración de retorno y reanuda el hilo A, ocurrirá lo siguiente: Como A se detuvo justo antes de llamar a initDateTime, A ahora llama a initDateTime(), que tipo de reiniciará objeto datetime, estableciendo datetime.colonTime para anular nuevamente. Luego, el hilo A ingresará al segundo bloque if, pero el programador interrumpirá A antes de datetime.colonTime = sb.toString(); se llama. Como conclusión, dateTime.colonTime sigue siendo nulo. Ahora el planificador reanuda B y el método devuelve nulo.
Me trataron de provocar la condición de carrera por tener un número de hilos de llamada getColonTime() a una sola instancia (final) de MyDateTime, pero sólo falla en algunos casos raros extreeemly :( Alguna pista cómo escribir un JUnit "prueba"?
Podría intentar primero utilizar el depurador para provocar la condición de carrera. Es decir. inicie un hilo, péguelo en un punto de interrupción (como entre if) y comience otro - y así sucesivamente. Después de que tengas la idea de cómo ocurre RC (parece que ahora no tienes nada de eso) podrías escribir una prueba de unidad exitosa – pupssman
No veo cómo podrías llegar al 'datetime de devolución '.colonTime; 'y recuperar null. ¿Estás seguro de que no hay problema con la forma en que estás construyendo la cadena hh: mm? Tal vez agregue ese código a su pregunta para que podamos ver eso. – Windle
Agregué algunas explicaciones adicionales sobre por qué puede suceder. Tengo que admitir que no es muy obvio – user3001