Pregunta

Tengo un objeto estático definido en mi clase de registro, en la línea de:

   class myLoggingClass {
     static java.util.Properties properties;
     ...
     ...
   }

Según mi libro de referencia, esto significa que el objeto de propiedades es compartido por todas las instancias de mi clase.

Me parece insuficiente esta definición. Estoy escribiendo una clase que se invoca más de una vez en cada aplicación de nuestro proyecto.

Además, nuestro proyecto utiliza varios servicios web que se ejecutan en el mismo contenedor tomcat. Cada servicio web puede tener múltiples hilos.

La máquina virtual Java que se ejecuta en el host también puede ejecutar una o más aplicaciones cliente de servicio web, que se ejecutan de forma externa a tomcat.

Entonces, según esta definición, es posible que Tomcat ejecute varios servicios web con subprocesos, cada uno con varios objetos, que pueden contener una instancia de mi clase.

También puede haber uno o dos clientes web que se ejecutan fuera de tomcat, pero dentro de la misma JVM. ¿Compartirían todas estas instancias de mi clase el mismo objeto de propiedades? Eso lo haría en todo JVM.

Si el objeto estático no tiene JVM, ¿alguien sabe a qué nivel existiría cada uno? ¿Uno por contenedor tomcat? ¿Uno por servicio web y otro por aplicación de cliente de servicio web independiente?

El motivo: cuando actualizo mis propiedades, obtengo una excepción java.lang.ConcurrentUpdateException de java.util.Properties.

Estoy usando una variable booleana estática para " bloquear " el objeto de propiedades cuando mi clase lo actualiza, pero esto no impide que se produzca la excepción.

Esto me lleva a creer que el objeto estático usado en mi clase puede no estar en el mismo nivel de alcance que el utilizado en java.util.Properties ... Pero eso es solo una suposición.

Gracias por cualquier ayuda.

¿Fue útil?

Solución

La causa probable de su ConcurrentModificationException es que está iterando a través de los valores / entradas del objeto Properties en un hilo mientras que otro lo modifica al mismo tiempo. No puedes hacer esto.

¿Puede explicar el mecanismo de bloqueo que menciona aquí?

  

Estoy usando una variable booleana estática para " bloquear " el objeto de propiedades cuando mi clase lo actualiza, pero esto no impide que se produzca la excepción.

?

Porque no suena como si estuvieras usando los métodos de bloqueo y sincronización integrados en Java.

Algo como esto debería evitar que los subprocesos lean el objeto Propiedades mientras que otro subproceso lo actualiza:

static Object lockObject = new Object();

...

synchronized(lockObject) {
     // access the Properties object
}

Tenga en cuenta que tendrá que hacer esto cada vez que acceda al objeto Propiedades, ya sea para leerlo o modificarlo.

Además, nunca recomendaría objetos estáticos para compartir datos entre todas las instancias o lockObjects estáticos: los datos globales son malos, pero parece que lo necesitas por algún motivo.

Otros consejos

Las estadísticas no están compartidas por todas las instancias de una clase " - están no relacionados con las instancias; pertenecen al tipo mismo . En particular, las variables estáticas se pueden utilizar perfectamente sin que se creen instancias .

Eso da una pista sobre el alcance de las estadísticas: están controladas por el objeto Class que representa la clase contenedora, que a su vez está controlada por el ClassLoader que cargado.

Según la ubicación de la biblioteca, la variable estática puede abarcar toda la JVM o la aplicación web, o posiblemente algo intermedio, si Tomcat admite el alojamiento múltiple (no puedo recordar de antemano).

Consulte la documentación de Tomcat para ver cómo están distribuidas las bibliotecas y cómo se relacionan con los cargadores de clases. Por ejemplo, aquí está el Guía de instrucciones del ClassLoader de Tomcat 6.0 , y el equivalente a 5.5 .

¿Cómo se bloquea " Boolean " " ¿trabajo? Debería usar un bloqueo adecuado ( sincronizado ) para asegurarse de que cada uso del objeto de propiedades (tanto de lectura como de escritura, incluido el bloqueo durante todo el período durante el cual lo itere) esté correctamente bloqueado.

En lugar de cambiar el " en vivo " Propiedades , ¿ha considerado el tratamiento como inmutable? por lo tanto, cuando quiera actualizar las propiedades, tome una copia, cámbiela y luego haga la copia en " en vivo " ¿versión? Aún debe evitar que dos hilos diferentes realicen cambios al mismo tiempo (o perdería algunos) pero es probable que la lectura sea mucho más fácil y más eficiente.

Es posible que el alcance de dicha variable static esté limitado a uno por ClassLoader que haya cargado su clase. No estoy seguro de cómo Tomcat organiza sus ClassLoaders, por lo que es difícil decir cuál será el alcance del alcance en ese entorno.

¿Podría tratarse de un problema de cargador de clases en el que el archivo jar que contiene su clase se duplica en cada WEB-INF / lib de sus diferentes aplicaciones? Si es así, intentaría agregar este jar a las librerías de Tomcat y no a la aplicación.

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