progreso - j progress bar java
¿Qué tan pesados son los monitores de Java? (3)
Creo que Collections.synchronizedCollection permite que un hilo acceda a la colección. Sin embargo, existe el problema de crear monitores.
Digamos que tengo una matriz de miles de objetos y una pequeña cantidad de hilos que pueden acceder a cada uno de los objetos. Quiero proteger el acceso a uno de los métodos de los objetos. La manera más fácil sería declarar ese método como synchronized
. Sin embargo, eso podría dar como resultado la creación de miles de monitores, cualquiera que sea la forma en que se implementen. Si esto fuera Win32, nunca crearía miles de objetos kernel como Mutex, pero CRITICAL_SECTION podría ser plausible. Me pregunto cuál es el caso en Java. Dada la posibilidad de que la disputa sea baja, ¿el uso de monitores impondría más que la cantidad de memoria que requieren? ¿Qué tan común es la práctica de usar una sincronización de granularidad tan baja en Java?
(Obviamente hay soluciones como usar una matriz mucho más pequeña de objetos de sincronización, a los que se accederá usando algo de hash. No estoy buscando una solución práctica, estoy buscando una idea).
Ya pagaste (la mayoría y la baja contención) la penalización por tener los monitores alrededor mediante el uso de Java ... no tiene sentido no usarlos. Particularmente en el caso de baja contención, son muy baratos (véanse los puntos 2.1, 2.2, 2.3 aquí y el ítem n. ° 1 aquí ), y la JVM puede optimizarlos totalmente para un número de casos. Si solo usa el monitor del objeto de forma transitoria, la JVM lo hará "lo suficientemente grande" (lo que significa que comienza como un cambio de bit, puede expandirse para casos de contención simples a un indicador atómico asignado a la pila y bajo persistencia puede tener asignado un esto, todos estos se desenrollarán de vuelta a la carcasa de bajo nivel cuando la contención disminuya) y recuperará el espacio más tarde. En la medida en que bloquear estos objetos es lo "correcto" en el lado de la aplicación, yo diría que síganlo.
Sin embargo, hay un olor de diseño aquí. Bloquear tantos objetos no suena bien. Además, si tiene alguna condición de bloqueo secuencial, no podrá razonar sobre bloqueos potenciales. Sugiero que aumente su pregunta con más detalles sobre la aplicación, y podemos preguntar si el bloqueo en un grupo grande de objetos es lo correcto.
Esta presentación de Dave Dice ofrece información útil sobre cómo funciona la sincronización de Java6, y esta entrada de blog es un tesoro oculto de información de sincronización en Java . Si realmente, realmente te importa cuán "grande" es una estructura de monitor de objetos completa (entrará en juego en el caso contencioso), el código está aquí . La página wiki interna de HotSpot también tiene información buena y detallada .
Los mutexes Java son lo suficientemente baratos como para tener cientos de miles de objetos sincronizados y no notarlos.
En el caso no reconocido, un mutex de Java consta de solo 2 bits en la palabra de banderas. La JVM solo asocia un objeto de bloqueo de SO pesado con un mutex de Java cuando se contenta el mutex, y luego libera el bloqueo del sistema operativo cuando todos los hilos han salido del mutex.
En las diapositivas 9 a 23 de esta presentación de Javaone 2006 se puede encontrar una descripción general de cómo se implementan los mutexes de Java.
Tenga en cuenta que la implementación y el rendimiento de mutexes es probable que dependan del proveedor / versión de Java que esté utilizando y de la plataforma en la que se esté ejecutando.
- En las primeras versiones de Java, los mutexes eran significativamente más caros.
- Es posible que haya habido avances desde el artículo de JavaOne 2006 ... ya sea publicado o no.