java multithreading synchronization error-detection

Cómo detectar violaciones de sincronización con Java



multithreading synchronization (9)

Además de la mención de @ Fernando sobre el bloqueo de hilos, otro problema con los hilos múltiples son las modificaciones concurrentes y los problemas que puede causar.

Una cosa que Java hace internamente es que una clase de recopilación cuenta cuántas veces se ha actualizado. Y luego un iterador verifica ese valor en cada .next () con respecto a lo que era cuando se creó el interator para ver si la colección se ha actualizado mientras iteraba. Creo que ese principio podría usarse de manera más general.

Me pregunto qué buenas maneras se podrían hacer afirmaciones sobre la sincronización o algo así para poder detectar violaciones de sincronización (durante la prueba).

Eso se usaría, por ejemplo, para el caso de que tuviera una clase que no es segura para subprocesos y que no va a ser segura para subprocesos. De alguna manera tendría alguna afirmación que me informaría (log o algo así) si se llamaba a algún método desde varios hilos.

Estoy anhelando algo similar que podría hacerse para AWT envío de hilo con lo siguiente:

public static void checkDispatchThread() { if(!SwingUtilities.isEventDispatchThread()) { throw new RuntimeException("GUI change made outside AWT dispatch thread"); } }

Solo querría algo más general. La descripción del problema no es tan clara, pero espero que alguien tenga algunos buenos enfoques =)


Cuando surge un problema sobre los hilos en Java, generalmente se relaciona con la detección de interbloqueos, más que simplemente monitoreando qué hilos están accediendo a una sección sincronizada al mismo tiempo. La extensión JMX , agregada a JRE desde 1.5, puede ayudarte a detectar esos bloqueos. De hecho, utilizamos JMX dentro de nuestro propio software para detectar automáticamente los bloqueos y un rastro donde se encontró.

Aquí hay un ejemplo sobre cómo usarlo.


Para el ejemplo específico que das, SwingLabs tiene algún código de ayuda para detectar violaciones y bloqueos de eventos. https://swinghelper.dev.java.net/

Hace un tiempo, trabajé con las herramientas de perfilación Java de JProbe. Una de sus herramientas (¿threadalyzer?) Buscaba violaciones de sincronización de subprocesos. Al mirar su página web, no veo una herramienta con ese nombre o todo lo que recuerdo. Pero es posible que desee echar un vistazo. http://www.quest.com/jprobe/performance-home.aspx


Puede que le interese un enfoque sobre el que Peter Veentjer escribió un blog, al que llama The Concurrency Detector . No creo que haya abierto esto todavía, pero como él lo describe, la idea básica es usar AOP para instrumentar el código que le interesa en el perfil, y registrar qué hilo ha tocado en qué campo. Después de eso, se trata de analizar sintácticamente o manualmente los registros generados.



Si puede identificar las clases inseguras de subprocesos, el análisis estático podría indicarle si alguna vez "escaparon" para hacerse visibles para varios subprocesos. Normalmente, los programadores hacen esto en sus cabezas, pero obviamente son propensos a errores en este sentido. Una herramienta debería ser capaz de utilizar un enfoque similar.

Dicho esto, del caso de uso que describes, parece algo tan simple como recordar un hilo y hacer afirmaciones sobre él para tus necesidades.

class Foo { private final Thread owner = Thread.currentThread(); void x() { assert Thread.currentThread() == owner; /* Implement method. */ } }

La referencia del propietario todavía se llena incluso cuando las aserciones están deshabilitadas, por lo que no es completamente "libre". Tampoco me gustaría complicar muchas de mis clases con esta repetición.

El método Thread.holdsLock (Object) también puede serle útil.


IntelliJ IDEA tiene muchas inspecciones concurrentes útiles. Por ejemplo, le avisa cuando está accediendo al mismo objeto desde contextos sincronizados y no sincronizados, cuando está sincronizando en objetos no finales y más.

Del mismo modo, FindBugs tiene muchas verificaciones similares.


Usted está buscando el santo grial, creo. AFAIK no existe, y Java no es un lenguaje que permita que ese enfoque se pueda crear fácilmente.

"Java Concurrency in Practice" tiene una sección sobre pruebas para enhebrar problemas. Llama especialmente la atención sobre lo difícil que es hacer.


Pruebe Contest o Covertity

Ambas herramientas analizan el código para descubrir qué partes de los datos pueden compartirse entre hilos y luego instrumentan el código (agregan código de bytes adicional a las clases compiladas) para verificar si se rompe cuando dos hilos intentan cambiar algunos datos al mismo tiempo. . Los dos hilos se ejecutan una y otra vez, cada vez comenzando con un desplazamiento de tiempo ligeramente diferente para obtener muchas combinaciones posibles de patrones de acceso.

Además, verifique esta pregunta: ¿ Unidad probando una aplicación multiproceso?