2010-10-28 12 views
14

En sistemas altamente concurrentes, puede ser difícil estar seguro de que su uso de bloqueos es correcto. Específicamente, pueden producirse interbloqueos si se adquieren bloqueos en un orden que no se esperaba mientras se adquiría en el orden correcto en otro hilo.Aserción del orden de sincronización en Java

Existen herramientas (por ejemplo, Coverity) que pueden realizar análisis estáticos en una base de código y buscar órdenes de bloqueo "inusuales". Me gustaría explorar otras opciones para satisfacer mis necesidades.

¿Existen herramientas livianas * para instrumentar código Java que pueda detectar casos en los que los bloqueos se adquieren en un orden distinto al esperado? Estoy de acuerdo con llamar explícitamente órdenes de bloqueo a través de comentarios/anotaciones.

Se prefieren las soluciones de fuente abierta o gratuita. Por favor, también comente si hay enfoques sin instrumentación para este problema.

* Para mis propósitos, medios de peso ligero ...

  • Si se trata de la instrumentación, todavía puedo ejecutar mi programa con el mismo estadio rendimiento. 30-50% de degradación es aceptable, supongo.
  • No tengo que pasar la mitad del día interactuando con la herramienta solo para obtener un "visto bueno". Idealmente, solo debería notar que lo estoy usando cuando hay un problema.
  • Si se trata de instrumentación, debería ser fácil desactivarla para entornos de producción.
  • No debería saturar mi código en cada declaración synchronize. Como mencioné anteriormente, estoy de acuerdo con comentar/anotar explícitamente los objetos o clases de objetos que se bloquean con ordenamientos relativos.
+1

... es por eso que Actor Model y STM son cada vez más populares –

+0

Alguien tenía una respuesta que hacía referencia a java.lang.Thread.holdsLock (Object) que se eliminó rápidamente. No pude encontrar ese método por mi cuenta, gracias por el puntero. Mi pregunta sigue en pie, sin embargo. –

+0

¿Has encontrado algo decente para hacer algo como eso? Tengo un código de detección de interbloqueo bastante sofisticado en C++ y en mi caso me gustaría instrumentar nuestro código Java para detectar casos en los que los bloqueos en C++ y/o en el lado de Java podrían interferir entre sí y provocar interbloqueos. – Pavel

Respuesta

3

No he utilizado AspectJ, por lo que no puedo garantizar la facilidad de uso. He usado ASM para crear un generador de perfiles personalizado, esto fue de aproximadamente 2 días de trabajo. El esfuerzo para sincronizar el instrumento debería ser similar. AspectJ debería ser más rápido y fácil una vez que estés al día con los aspectos.

Implementé el rastreo de detección de punto muerto para nuestro servidor basado en C++. Aquí es cómo lo hice:

  • Cuando alguna vez adquirir o quitar un bloqueo tracé:
    • <time> <tid> <lockid> <acquiring|releasing> <location in code>
  • Esta traza rendimiento extra afectada de manera drástica y no era utilizable en la producción.
  • Entonces, cuando se descubrió un posible punto muerto en la producción, utilicé el archivo de registro para descubrir qué sucedía en el punto muerto. Luego, reproduje esta funcionalidad en un entorno de prueba con mi seguimiento activado.
  • Luego ejecuté un script en el archivo de registro para ver si era posible un bloqueo y cómo.He utilizado un script awk, el uso de este algoritmo:
    • línea Foreach
      • si la adquisición
        • añadir lockid a la lista de bloqueos actuales para este hilo
        • añadir cada par de bloqueos en esta lista a un conjunto pares de bloqueo para este hilo. por ejemplo, para la lista de Lock A -> Lock B -> Lock C generar los pares de (Lock A, Lock B), (Lock A, Lock C), (Lock B, Lock C)
      • si la liberación de
        • quitar lockid actual de la cola de la lista para esta hilo
    • Para cada búsqueda pair bloqueo todos los otros hilos para el pares de bloqueo inverso, cada coincidencia es un posible punto muerto, así que imprima los pares y los hilos afectados.
    • En lugar de hacer el algoritmo más inteligente, compré e bloqueo de adquisición para ver si fue un punto muerto real.

Hice esto después de no poder encontrar la causa de un punto muerto durante varios días, se tomó un par de días más para poner en práctica y unas pocas horas para encontrar el punto muerto.

Si usted está considerando este enfoque en las cosas de Java a considerar son:

  • ¿Sólo se utiliza synchronized para proteger sus secciones críticas? ¿Estás usando las clases en java.lang.concurrent? (estos pueden requerir manejo/instrumentación especial)
  • ¿Qué tan fácil es imprimir la ubicación del código con aspectos/ASM? Usé __FILE__ y __LINE__ en C++. ASM le dará el nombre de clase, el nombre del método y la firma.
  • No puede instrumentar los bloqueos utilizados para proteger su seguimiento/registro.
  • Puede optimizar su instrumentación si utiliza un archivo de registro por subproceso y enruta el almacenamiento local para el objeto de archivo.
  • ¿Cómo identifica de forma única los objetos que sincroniza? Tal vez toString() y System.identityHashCode() serían suficientes, pero podrían requerir más. Usé la dirección del objeto en C++.
+0

Esta es una solución razonable, pero esperaba que hubiera una herramienta que hiciera todo ese trabajo por mí. Yendo a ver más ASM, gracias. –

0

no le consigue todo el camino, pero un buen comienzo es utilizar el JCIP annotations y FindBugs atrapa un par de cosas.

+0

A menos que me falta algo, FindBugs no tiene ningún control para ordenar el monitor (bloques sincronizados). –

+0

@Derrick Rice: No tenía conocimiento de ninguna herramienta que hiciera exactamente lo que el OQ estaba pidiendo, pero me proporcionó algo cerca ... – andersoj

1

Puede usar AspectJ, que es relativamente fácil de aprender y le permitirá configurar su propia forma personalizada y simplificada de controlar sus hilos y los bloqueos a los que accedan.

+1

Gracias. Seguí esta idea hasta que llegué a este documento, "Un punto de unión para el Bloque Sincronizado en AspectJ": http://www.cs.man.ac.uk/~xic/SBJP_AspectJ.pdf –

+0

Buen trabajo. Gracias por compartir el enlace, y lo siento si las desventajas no lo hacen utilizable en su situación. –