Pregunta

Me pregunto qué buenas maneras habría de hacer afirmaciones sobre la sincronización o algo así para poder detectar violaciones de sincronización (durante las pruebas).

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

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

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

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

¿Fue útil?

Solución

Estás buscando el santo grial, creo. AFAIK no existe, y Java no es un lenguaje que permita crear fácilmente este enfoque.

" Concurrencia de Java en la práctica " tiene una sección sobre pruebas para problemas de subprocesos. Llama especialmente la atención sobre lo difícil que es hacerlo.

Otros consejos

Cuando surge un problema sobre subprocesos en Java, generalmente está relacionado con la detección de punto muerto, más que simplemente monitorear qué subprocesos están accediendo a una sección sincronizada al mismo tiempo. la extensión JMX , agregada a JRE desde 1.5, puede ayudar detectas esos callejones sin salida. De hecho, utilizamos JMX dentro de nuestro propio software para detectar automáticamente puntos muertos y rastrear dónde se encontró.

Aquí hay un ejemplo sobre cómo usarlo.

IntelliJ IDEA tiene mucha concurrencia útil inspecciones . Por ejemplo, le advierte cuando está accediendo al mismo objeto desde contextos sincronizados y no sincronizados, cuando está sincronizando objetos no finales y más.

Del mismo modo, FindBugs tiene muchos similares comprueba .

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

Una cosa que Java hace internamente es que una clase de colección lleva un recuento de cuántas veces se ha actualizado. Y luego un iterador comprueba ese valor en cada .next () contra lo que era cuando se creó el interador para ver si la colección se ha actualizado mientras estaba iterando. Creo que ese principio podría usarse de manera más general.

Pruebe ConTest o Covertity

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

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

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

Si puede identificar clases inseguras de hilos, el análisis estático podría decirle si alguna vez "escapan" hacerse visible para múltiples hilos. Normalmente, los programadores hacen esto mentalmente, pero obviamente son propensos a cometer errores a este respecto. Una herramienta debería poder utilizar un enfoque similar.

Dicho esto, por el caso de uso que describe, suena como algo tan simple como recordar un hilo y hacer afirmaciones sobre él podría ser suficiente para sus necesidades.

class Foo {

  private final Thread owner = Thread.currentThread();

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

}

La referencia del propietario todavía se rellena incluso cuando las aserciones están deshabilitadas, por lo que no es completamente gratis. Tampoco me gustaría saturar muchas de mis clases con este repetitivo.

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

Para el ejemplo específico que proporcione, SwingLabs tiene un código auxiliar para detectar violaciones de eventos y bloqueos. https://swinghelper.dev.java.net/

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

Puede usar Netbeans profiler o JConsole para verificar en profundidad el estado de los hilos

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top