2008-11-18 14 views
9

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).Cómo detectar violaciones de sincronización con Java

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 anhelo de algo similar que se podría hacer para AWT hilo de despacho con lo siguiente:

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

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

Respuesta

2

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 problemas de subprocesamiento. Llama especialmente la atención sobre lo difícil que es hacer.

0

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 creación de perfiles Java de Java. 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

2

Cuando surge un problema sobre los subprocesos en Java, generalmente está relacionado con la detección de interbloqueos, más que simplemente monitoreando qué subprocesos están accediendo a una sección sincronizada al mismo tiempo. La extensión JMX, agregada a JRE desde 1.5, puede ayudarlo 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 example acerca de cómo usarlo.

1

Además de la mención de @ Fernando de bloqueo de subprocesos, otro problema con varios subprocesos es las modificaciones simultáneas 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 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.

1

Trate ConTest o Covertity

Ambas herramientas analizar el código de averiguar qué partes de los datos pueden ser compartidos entre los hilos y luego instrumento del código (añadir código de bytes extra para las clases compiladas) para comprobar 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.

Compruebe también esta pregunta: Unit testing a multithreaded application?

1

Usted puede estar interesado en un enfoque Peter Veentjer blogs sobre, 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.

1

Si puede identificar las clases de subprocesos no seguros, el análisis estático podría indicarle si alguna vez "escaparon" para ser 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, suena como algo tan simple como recordar un hilo y hacer afirmaciones sobre él podría ser suficiente 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 rellena, incluso cuando las aserciones están deshabilitadas, por lo que no es del todo "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.

2

IntelliJ IDEA tiene mucha concurrencia útil inspections. 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 muchos similares checks.

+0

inspecciones de concurrencia útiles ... como? :) – bvdb

Cuestiones relacionadas