2011-04-06 9 views
7

Below bean no es seguro para subprocesos: el método addIfNotExist no está sincronizado, por lo que es posible que el mismo término se agregue dos veces debido a la condición de raza. Anoté la clase usando la anotación JCIP @ThreadSafe esperando que FindBugs encuentre que la implementación no es segura para subprocesos y la marque como un error, pero no lo es. ¿Hay alguna herramienta que identifique este tipo de errores en la base de códigos?detección de condición de carrera utilizando findbugs u otra herramienta de análisis

Los métodos addIfNotExist e isExist deben estar sincronizados para que este bean sea seguro para subprocesos. ¿Debería el método isExist también estar sincronizado?

package com.test; 

import java.util.ArrayList; 

import java.util.Collection; 

import net.jcip.annotations.GuardedBy; 

import net.jcip.annotations.ThreadSafe; 

@ThreadSafe 

public class Dictionary { 

    @GuardedBy("this") 
    public Collection<String> terms = new ArrayList<String>(); 

    public void addIfNotExist(final String input) { 
     if (!this.terms.contains(input)) { 
      this.terms.add(input); 
     } 
    } 

    public boolean isExist(final String input){ 
     return this.terms.contains(input); 
    } 

    public void remove(final String input){ 
     this.terms.remove(input); 
    } 
} 

Respuesta

4

Es tremendamente difficult escribir código multi-hilo de seguridad que tiene un grado de complejidad: este tipo de bloqueo (utilizando monitores) está plagado de todo tipo de condiciones de carrera intermitentes, puntos muertos y cuestiones livelock que a menudo elude detección hasta la promoción en los sistemas de producción; si puede, considere usar message passing, software transactional memory o persistent data structures en su lugar. FindBugs (o cualquier herramienta de análisis estático) solo puede detectar códigos no peligrosos: por definición, las condiciones de carrera son temporales, requieren muchas ejecuciones para manifestarse, por lo que el análisis estático falla a este respecto porque no ejecutan ningún código y solo buscan firmas de código comunes. El mejor en mi humilde opinión las cosas para detectar problemas son:

  • Un segundo par de ojos - rigurosas revisiones de código con los compañeros que están familiarizados con el código - va un largo camino en la búsqueda de errores que no son inmediatamente obvias para el autor original.

  • La integración continua & exhaustivas pruebas automatizadas que ejercen múltiples threadedness en una variedad de hardware y implacablemente investigan los fallos intermitentes de prueba ''.

En respuesta a la segunda pregunta, sí, todos los métodos que hacen alguna referencia a terms deben ser vigilados por un monitor de sincronización, independientemente de si se trata de una operación de lectura o escritura; considere lo que sucede si el hilo A llama al remove("BOB"), mientras que el hilo B llama al isExists("BOB") cuando no tiene sincronización: el hilo A compactará la lista de arreglo mientras que el hilo B intentará atravesarlo.

En el mejor de los casos, no podrá determinar el resultado de isExists("BOB"), pero es completamente posible que B pueda lanzar intermitentemente una excepción IndexOutOfBounds ya que el tamaño de la matriz podría haber cambiado (es decir, reducido) al ser atravesado .

Sincronice, y mientras todavía no pueda estar seguro del orden en que se realizan las llamadas (debido a la naturaleza no determinística de la programación), pero al menos se le garantizará que las operaciones en terms serán atómicas - es decir, no están siendo alterados por otra cosa mientras se está ejecutando el hilo actual.

+0

Gracias por su respuesta -. su razonamiento sobre por qué isExists deben estar sincronizados tiene sentido – dsatish

3

Esto es algo que se puede utilizar en tiempo de ejecución (durante las pruebas automatizadas unidad o pruebas de integración o lo que sea) a ayuda encontrar problemas de roscado: Descripción IBM ConTest (Concurrency Testing)

concurso: "La tecnología Concurso es innovador y contra-intuitivo.Específicamente, ConTest programa de forma sistemática y transparente la ejecución de subprocesos de programa de manera que los escenarios de programa que probablemente contengan condiciones de carrera, interbloqueos y otros errores intermitentes (llamados colectivamente problemas de sincronización) se ven obligados a aparecer con alta frecuencia. Al hacerlo, ConTest mejora dramáticamente la calidad de las pruebas y reduce los gastos de desarrollo, ya que los errores se encuentran antes en el proceso de prueba. "

+4

Dónde. ¿Puede uno descargar ConTest? Todo lo que he encontrado han sido enlaces muertos y resultados de búsqueda vacíos. –

1

encontrar tales bloques de código incorrectamente sincronizados, utilizo el siguiente algoritmo:.

Registro de los hilos de todas las modificaciones de campo utilizando instrumentación Si un campo es modificado por más de un hilo sin sincronización, he encontrado . una carrera de datos

que implementa este algoritmo en el interior http://vmlens.com, que es una herramienta dinámica para encontrar carreras de datos dentro de los programas de Java

Cuestiones relacionadas