2009-10-22 10 views
18

Vi this publicar en SO ya, pero todavía plantea la pregunta, al menos para Java. Parece que esto debería ser un problema apremiante para cualquier aplicación (estoy probando una aplicación web para este caso de uso) que tiene varios subprocesos. ¿Cómo lo han tratado ustedes de una manera que permite que sus hilos se entrelacen, lo que significa, de manera inherente, probar el comportamiento de un hilo aleatorio?¿Cómo puedo probar con eficacia el código concurrente (unidad/integración) en Java?

Respuesta

9

creo que es inherentemente difícil, ya que usted está mirando para probar la ausencia de algo en un sistema que no es determinante (posiblemente). Una vez dicho esto, siempre vale la pena escribir pruebas repetibles para enfatizar los componentes de múltiples subprocesos. Si ocurre un problema, es posible que no puedas repetirlo, pero quizás puedas encontrar el error por inspección. Así que asegúrese de que sus pruebas registran las excepciones pertinentes en gran detalle (y posiblemente los parámetros de entrada, etc.)

Es también digno de funcionamiento de un analizador de código estático. Estos recogerán (entre otras cosas) la sincronización inconsistente de las variables e inmediatamente resaltarán las áreas de preocupación. FindBugs es una de esas herramientas.

0

Una buena manera de probar esto es asegurarse de que tiene acceso a una máquina multi-CPU, a continuación, ejecutar la prueba durante todo el tiempo una vez/con tantas repeticiones como sea posible. Por ejemplo, si tiene un algoritmo de consumidor productor multiproceso, llene la cola con una lista de buen tamaño y use 2x tantos hilos como sea posible en producción. Esto debería al menos darle la oportunidad de atacar una condición de carrera o un problema de sincronización más comúnmente. Luego ejecute esta prueba en una compilación diaria.

3

he típicamente dio lugar a un número enorme (100) como los hilos en una prueba de unidad y los envió contra él con la esperanza de golpear a una condición de carrera :). Lamentablemente, eso no es muy definitivo. Sin embargo, puede mejorar sus probabilidades al tener líneas de depuración en las áreas sensibles de sus hilos que hacen que el hilo activo duerma para X millis. Esta estrategia le permite dejar ventanas abiertas donde otros hilos pueden intercalarse. Estas líneas solo estarían activas durante la prueba unitaria (aspectos de uso o líneas de código rígido que solo se activan cuando se establece un indicador de depuración).

Probar un negativo es difícil de conseguir. Realmente no puedes probar que no tienes un problema de concurrencia. Todo lo que puede hacer es configurar sus pruebas para ejercitarlo lo más exhaustivamente posible.

+0

He intentado este método ad-hoc en un '@ test' y ni siquiera se registran, el hilo actúa sobre un método que desencadena una' @ aspecto Before' que establece un 'ThreadLocal' en ese hilo que se usado en otra parte en el punto final hilos - se trata de un caso de uso complejo construido alrededor de la APP, la pesadilla de mi existencia es para averiguarlo una prueba multi-hilo. Junit normal funciona bien sin embargo. –

0

Mi respuesta a esto es para evitar crear situaciones en las que pueda haber condiciones de carrera con un uso juicioso del diseño inteligente y la tecnología existente. Por ejemplo, si su aplicación MT usa elementos de trabajo independientes, puede insertar un agente JMS en su aplicación para utilizarlo como un mecanismo de comunicación entre los hilos. De manera similar, con los recursos del sistema que pueden estar sujetos a condiciones de carrera, no haga esas partes de subprocesos múltiples. Si tiene archivos que necesita escribir, haga que un hilo sea responsable de escribirlos utilizando información pasada a través del subsistema JMS.

En última instancia no hay pintura a través de los números de unidad de código de prueba MT para asegurarse de que no es vulnerable a una condición de carrera.

2

Sugiero que obtenga Java Concurrency in Practice - no solo le dice cómo evitar las condiciones de carrera en primer lugar, hay una sección sobre prueba de simultaneidad.

También existen herramientas de análisis estático de concurrencia disponibles para Java - por desgracia, aunque sé que están ahí fuera, no he estado en una posición para evaluarlas.

-1

No se debe probar el código que posiblemente falle debido a problemas de enhebrado no deterministas. En cambio, debería eliminarse y reemplazarse por algo que pueda ser.

La mayoría de las veces esto se puede hacer simplemente haciendo un único subproceso: solo una pequeña fracción de las aplicaciones necesita el menor aumento de escalabilidad que proporciona la programación preventiva en proceso. Alternativamente, se puede configurar una arquitectura de hebras, donde se utiliza el sistema operativo, compilador o una herramienta de terceros para proporcionar una garantía dura que las operaciones no deterministas no pueden tener lugar.

Cuestiones relacionadas