2010-11-01 6 views
15

Supongamos que tengo una matriz de miles de objetos y un pequeño número de subprocesos 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_SECTIONs 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?¿Qué tan pesados ​​son los monitores de 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).

+1

Los objetos Java vienen con un bloqueo de peso ligero integrado. Esta memoria se utiliza tanto si bloquea el objeto como si no. En resumen, Java está diseñado y optimizado para admitir el bloqueo de objetos. –

+0

10 lbs –

Respuesta

14

Ya ha pagado (la mayoría de, y en baja contención) la penalización por tener los monitores alrededor usando Java ... no tiene sentido no usarlos. Particularmente en el caso de baja contención, son muy baratos (ver Items 2.1, 2.2, 2.3 here y Item #1 here), 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 por 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, aquí hay un olor de diseño. Bloquear tantos objetos no suena bien. Además, si tiene alguna condición de bloqueo secuencial, no podrá razonar sobre posibles bloqueos. 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.

Este presentation by Dave Dice proporciona información útil sobre cómo funciona la sincronización Java6, y esta blog entry is a treasure trove of sync-on-Java information. Si realmente, realmente te importa cuán "grande" es una estructura de monitor de objetos completa (entrará en juego en el caso presentado), el code is here. La página wiki interna de HotSpot también tiene algunos good in-depth information.

+0

Usar Java no significa que ya pagué todas las posibles visitas de rendimiento por adelantado ... De todos modos, esta es definitivamente una cuestión de diseño. Mi nariz C++ sí huele, pero no me utilizan los aromas de Java ... En realidad, no me preocupan los puntos muertos, porque las operaciones son cortas y simples. En tales casos, es tentador simplemente lanzar un "sincronizado", y estar en el lado seguro. Sin embargo, me preocupa qué tan bien funcionará esa escala (sé que en Win32 no lo hará, porque los objetos kernel son caros). – eran

+0

@eran: Entendido. Si sabemos más sobre la aplicación, podemos profundizar en ella. Pero teniendo en cuenta lo que nos has contado, te diría que no te preocupes a menos que tengas un problema de rendimiento mensurable. En el caso no reconocido, ya pagó casi la totalidad de la multa; hay un pequeño costo de invertir un bit ya asignado en alguna parte para monitorenter/exit. Si realmente ves alguna contención no trivial, es posible que necesites cavar más profundo. – andersoj

+0

@eran: si se trata de una aplicación de alto rendimiento para la que está dispuesto a invertir una atención seria de bajo nivel, y desea la teoría profunda, eche un vistazo a la Programación Artificial de Multiprocesador de Herlihy, http: // www. elsevier.com/wps/find/bookdescription.cws_home/714091/description precaución: cosas profundas. Pero el código y el análisis de Java están disponibles para todo el contenido. – andersoj

0

Creo que Collections.synchronizedCollection permite que un hilo acceda a la colección. Sin embargo, existe el problema de crear monitores.

6

Los mutexes de Java son lo suficientemente baratos como para tener cientos de miles de objetos sincronizados sin tener en cuenta.

En el caso no reconocido, un mutex de Java consiste en 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.

Una visión general de cómo se implementan los mutex Java puede encontrarse en las diapositivas de 9 a 23 this presentation de JavaOne 2006.


Tenga en cuenta que la implementación y el funcionamiento de los mutex es susceptible de depender del vendedor/liberación de Java que está utilizando y la plataforma en la que se está ejecutando.

  • En versiones anteriores de Java, los mutexes eran significativamente más caros.
  • Puede haber avances desde el documento JavaOne 2006 ... publicados o no.
+0

+1 gran recurso que no había encontrado. Desearía que hicieran algún intento de agregar estas cosas en un solo lugar. – andersoj

Cuestiones relacionadas