¿Por qué todos los Objetos Java tiene wait() y notify() y esto causa un impacto en el rendimiento?

StackOverflow https://stackoverflow.com/questions/1648551

  •  22-07-2019
  •  | 
  •  

Pregunta

Cada Java Object tiene los métodos wait() y notify() (y variantes adicionales).Nunca he utilizado estos y sospecho que muchos otros no.¿Por qué son tan fundamentales que cada objeto tiene que tener ellos y hay un impacto en el rendimiento en disponer de ellos (es de suponer que algún estado se almacena en ellos)?

EDITAR para enfatizar la cuestión.Si tengo un List<Double> con 100.000 elementos, a continuación, cada Double ha estos métodos, como los que se extiende desde Object.Pero parece poco probable que todos estos tienen que saber sobre los hilos que manejan el List.

EDITAR excelente y respuestas útiles.@Jon tiene un muy buen blog que se cristalizaron mis sentimientos.También estoy completamente de acuerdo con @Bob_Cross que debe mostrar un problema de rendimiento antes de que preocuparse.(También como la enésima ley del éxito de idiomas si hubiera sido un impacto en el rendimiento, a continuación, Sol o que alguien se hubiera fijado).

¿Fue útil?

Solución

Bien, esto no significa que cada objeto tiene potencialmente tiene un monitor asociado.El mismo monitor se utiliza para synchronized.Si usted está de acuerdo con la decisión de ser capaz de sincronizar en cualquier objeto, entonces wait() y notify() no añadir más por el estado del objeto.La JVM puede asignar el monitor real perezosamente (yo sé .NET hace) pero tiene que ser algo de espacio de almacenamiento disponible decir que el monitor está asociado con el objeto.Es cierto que es posible que esta es una cantidad muy pequeña (por ejemplo,3 bytes) que realidad no iba a guardar la memoria de todos modos debido a que el relleno del resto de los objetos de gastos generales tendrías que mirar cómo cada individuo JVM manejado memoria para decir seguro.

Tenga en cuenta que sólo tienen métodos no afecta el rendimiento (salvo los muy ligeramente por el código evidentes de estar en el presente en algún lugar).No es como si cada objeto o, incluso, cada tipo tiene su propia copia del código de wait() y notify().Dependiendo de cómo las vtables de trabajo, cada tipo de puede terminar con un extra de entrada vtable para cada método heredado - pero eso es solo por el tipo de base, no una base por objeto.Eso es, básicamente, va a perderse en el ruido, en comparación con la mayor parte del almacenamiento, que es para los objetos reales ellos mismos.

Personalmente, creo que tanto .NET y Java cometido un error al asociar un monitor con cada objeto - prefiero tener una sincronización explícita de los objetos en su lugar.Escribí un poco más sobre esto en un post de blog sobre el rediseño de java.lang.Objeto/Sistema.Objeto.

Otros consejos

¿Por qué son tan fundamentales que cada objeto tiene que tener ellos y es hay un impacto en el rendimiento en disponer de ellos (es de suponer que algún estado se almacena en ellos)?

tl;dr:Son thread-métodos de seguridad y tienen pequeños gastos relativos a su valor.

Las realidades fundamentales que estos métodos de apoyo son los siguientes:

  1. Java es siempre multi-threaded.Ejemplo:echa un vistazo a la lista de los temas utilizados por un proceso de uso de jconsole o jvisualvm algún tiempo.
  2. La corrección es más importante que el "rendimiento". Cuando yo estaba proyectos de clasificación (hace muchos años), yo solía tener que explicar "llegar a la respuesta equivocada muy rápido todavía es incorrecto."

Fundamentalmente, estos métodos proporcionan algunos de los ganchos para administrar por Objeto monitores usados en la sincronización.En concreto, si tengo synchronized(objectWithMonitor) en un método en particular, puedo usar objectWithMonitor.wait() para producir ese monitor (por ejemplo, si necesito otro método para completar un cálculo antes de proceder).En ese caso, que le permitirá a uno con otro método que se bloquea en espera de que el monitor de proceder.

Por otro lado, puedo usar objectWithMonitor.notifyAll() para permitir que los Hilos que están a la espera para el monitor de saber que voy a renunciar al monitor pronto.Que en realidad no puede proceder hasta que me deje el bloque sincronizado, aunque.

Con respecto a los ejemplos específicos (por ejemplo, la larga lista de Dobles), donde usted puede preocuparse de que hay un rendimiento de memoria o el golpe en el mecanismo de supervisión, aquí hay algunos puntos que usted probablemente debería considerar:

  1. Primero, aquí está la prueba.Si usted piensa que hay un gran impacto a partir de un núcleo de Java mecanismo, tales como multi-threaded corrección, hay una excelente posibilidad de que su intuición es falso.Medir el impacto de la primera.Si es en serio y que saber que usted nunca tendrá que volver a sincronizar individual, Doble, considere el uso de dobles en su lugar.
  2. Si usted no está seguro de que usted, su compañero de trabajo, un futuro mantenimiento coder (que puede ser usted mismo un año más tarde), etc., nunca jamás nunca necesita una granularidad fina de theaded acceso a sus datos, hay una excelente posibilidad de que la toma de estos monitores de distancia sólo haría que su código sea más flexible y fácil de mantener.

Seguimiento en respuesta a la pregunta sobre por Objeto vsexplícito objetos del monitor:

Respuesta corta: @JonSkeet:sí, la eliminación de los monitores podría crear problemas:iba a crear fricción.Mantener a los monitores en Object nos recuerda que esta es siempre un sistema multiproceso.

El objeto integrado de los monitores no son sofisticados pero que son:fácil de explicar;trabajo en una forma predecible;y claro en su propósito. synchronized(this) es una clara declaración de intenciones.Si obligamos a los novatos de los codificadores para utilizar el paquete de concurrencia, exclusivamente, presentamos la fricción.¿Qué hay en el paquete?¿Qué es un semáforo?Fork-join?

Un novato programador puede utilizar el Objeto de monitores para escribir decente modelo-vista-controlador. synchronized, wait y notifyAll puede ser utilizado para implementar ingenuo (en el sentido de simple, accesible, pero tal vez no de sangrado-el rendimiento del borde) de hilo de seguridad.El ejemplo canónico sería uno de estos Dobles (el postulado de la OP), que puede tener un conjunto de hilos de un valor, mientras que el AWT hilo obtiene el valor para ponerlo en un JLabel.En ese caso, no hay ninguna buena razón para crear un explícito de Objetos adicionales sólo para tener un monitor externo.

En un nivel ligeramente más alto de complejidad, estos métodos son útiles como método de seguimiento.En el ejemplo de arriba, me hizo explícitamente que (ver objectWithMonitor fragmentos de arriba).De nuevo, estos métodos son muy útiles para reunir relativamente simple hilo de seguridad.

Si a usted le gustaría ser aún más sofisticado, creo que se debe pensar seriamente acerca de la lectura Java Concurrencia En La Práctica (si no lo has hecho ya).Leer y escribir los bloqueos son muy poderosos, sin añadir demasiado complejidad adicional.

Remate: El uso básico de los métodos de sincronización, usted puede aprovechar una gran parte de la actuación habilitado por los modernos procesadores multi-core con rosca de seguridad y sin un montón de sobrecarga.

Todos los objetos en Java tienen monitores asociados con ellos. Las primitivas de sincronización son útiles en casi todos los códigos de subprocesos múltiples, y es semánticamente muy agradable sincronizar en los objetos a los que está accediendo en lugar de en & Quot; Monitor & Quot; objetos.

Java puede asignar los Monitores asociados con los objetos según sea necesario, como lo hace .NET, y en cualquier caso la sobrecarga real para simplemente asignar (pero no usar) el bloqueo sería bastante pequeña.

En resumen: es realmente conveniente almacenar objetos con sus bits de soporte de seguridad de subprocesos, y hay muy poco impacto en el rendimiento.

Estos métodos existen para implementar la comunicación entre subprocesos.

Consulte este artículo sobre el tema .

Reglas para esos métodos, tomadas de ese artículo:

  • wait () le dice al hilo de llamada que abandone el monitor y se vaya a dormir hasta que algún otro   el hilo ingresa al mismo monitor y llama a notify ().
  • notify () activa el primer hilo que llamó a wait () en el mismo objeto.
  • notifyAll () activa todos los hilos que llamaron wait () en el mismo objeto. los   el hilo de mayor prioridad se ejecutará primero.

Espero que esto ayude ...

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