¿Por qué estas tan fundamental que cada objeto tiene que tener ellos y es hay un impacto en el rendimiento en disponer de ellos (presumiblemente algún estado se almacena en ellos)?
tl; dr: Son métodos de seguridad de hilos y tienen un costo pequeño en relación con su valor.
Las realidades fundamentales que these methods apoyo son que:
- Java es siempre multi-hilo. Ejemplo: revise la lista de subprocesos utilizados por un proceso utilizando jconsole o jvisualvm en algún momento.
- La corrección es más importante que el "rendimiento". Cuando estaba evaluando proyectos (hace muchos años), solía tener que explicar "llegar a la respuesta incorrecta realmente rápido sigue siendo incorrecto".
Fundamentalmente, estos métodos proporcionan algunos de los ganchos para administrar los monitores por objeto utilizados en la sincronización. Específicamente, si tengo synchronized(objectWithMonitor)
en un método particular, puedo usar objectWithMonitor.wait()
para obtener ese monitor (por ejemplo, si necesito otro método para completar un cálculo antes de poder proceder). En ese caso, eso permitirá que otro método sea bloqueado esperando que ese monitor proceda.
Por otro lado, puedo usar objectWithMonitor.notifyAll()
para dejar que los hilos que están esperando el monitor sepan que voy a renunciar al monitor pronto. Sin embargo, no pueden continuar hasta que abandone el bloque sincronizado.
Con respecto a ejemplos específicos (por ejemplo, largas listas de dobles) donde es posible que se preocupan de que hay un rendimiento o la memoria golpeado en el mecanismo de vigilancia, aquí hay algunos puntos que usted debe probablemente considerar:
- Primera , Pruébalo. Si cree que hay un impacto importante de un mecanismo central de Java, como la corrección de múltiples subprocesos, existe una gran posibilidad de que su intuición sea falsa. Mida el impacto primero. Si es grave y sabe que no necesitará sincronizar en un Doble individual, considere usar dobles.
- Si no está seguro de que usted, su compañero de trabajo, un futuro programador de mantenimiento (que podría ser usted mismo un año después), etc.nunca necesitará alguna vez necesita una gran granularidad de acceso a sus datos, hay una gran posibilidad de que quitar estos monitores solo haga que su código sea menos flexible y fácil de mantener.
Seguimiento en respuesta a la pregunta sobre vs. objetos explícitos de monitor por cada objeto:
Respuesta corta: @JonSkeet: sí, la eliminación de los monitores crearía problemas: se crearía fricción. Mantener esos monitores en Object
nos recuerda que esto es siempre un sistema multiproceso.
Los monitores de objetos incorporados no son sofisticados pero son: fáciles de explicar; trabajar de una manera predecible; y son claros en su propósito. synchronized(this)
es una clara declaración de intenciones. Si forzamos a los programadores principiantes a usar el paquete de concurrencia exclusivamente, introducimos la fricción. ¿Qué hay en ese paquete? ¿Qué es un semáforo? Tenedor-unirse?
Un codificador novato puede usar los monitores Object para escribir código decente modelo-vista-controlador. synchronized
, wait
y notifyAll
se puede utilizar para implementar ingenuo (en el sentido de simple, accesible, pero tal vez no de última generación) seguridad de hilos. El ejemplo canónico sería uno de estos Dobles (postulados por el OP) que puede tener un subproceso establecido un valor mientras que el subproceso AWT obtiene el valor para colocarlo en un JLabel. En ese caso, no hay una buena razón para crear un Objeto adicional explícito solo para tener un monitor externo.
En un nivel ligeramente más alto de complejidad, estos mismos métodos son útiles como un método de monitoreo externo. En el ejemplo anterior, explícitamente hice eso (vea los fragmentos de objectWithMonitor arriba). Una vez más, estos métodos son realmente útiles para armar seguridad de hilo relativamente simple.
Si desea ser aún más sofisticado, creo que debería pensar seriamente en leer Java Concurrency In Practice (si no lo ha hecho). Los bloqueos de lectura y escritura son muy potentes sin agregar demasiada complejidad adicional.
Punchline: Utilizando métodos de sincronización básicos, puede aprovechar una gran parte del rendimiento habilitado por los procesadores modernos multi-núcleo con seguridad de hilo y sin una gran sobrecarga.
Su ejemplo no está bien elegido, ya que String es inmutable y, por lo tanto, no tiene estado, lo que es relativamente poco frecuente. –
@Kevin - gracias. Editaré –