Red de conocimiento informático - Material del sitio web - Cómo usar esperar, notificar y notificar todo correctamente en Java

Cómo usar esperar, notificar y notificar todo correctamente en Java

En Java, puede utilizar esperar, notificar y notificar a todos para comunicarse entre subprocesos. Si tiene dos subprocesos en su programa Java, un productor y un consumidor, entonces el productor puede notificar al consumidor que comience a consumir datos porque el búfer de cola tiene algo para consumir (no vacío). En consecuencia, el consumidor puede notificar al productor que puede comenzar a generar más datos porque cuando consume algunos datos, el búfer ya no está lleno.

1. Usar esperas y notificaciones

Aunque los conceptos de esperas y notificaciones son muy básicos y ambos son funciones de clases de objetos, escribir código usándolos no es sencillo. Si les pide a los candidatos en las entrevistas que escriban código manualmente usando esperar y notificar para resolver un problema entre productor y consumidor, la mayoría de ellos se sentirán abrumados o cometerán errores, como usar la palabra clave sincronizada en el lugar incorrecto o no usar esperar en el objeto correcto. o no seguir los métodos de codificación estándar. Para ser honesto, este problema puede ser un verdadero dolor de cabeza para los programadores que no los utilizan con regularidad.

La primera pregunta es, ¿cómo utilizar wait() en el código? Dado que wait() no es una función de la clase thread, no puedes usar Thread.call(). De hecho, a muchos programadores de Java les gusta escribir así porque están acostumbrados a usar Thread.sleep (), por lo que intentarán usar wait () para lograr el mismo propósito, pero pronto se darán cuenta de que esto no resuelve el problema. pregunta sin problemas. El enfoque correcto es utilizar la espera en un objeto que se disfruta en varios subprocesos, que en un problema productor-consumidor es la cola del búfer.

La segunda pregunta es, dado que se debe llamar a esperar en una función u objeto sincronizado, ¿qué objeto se debe sincronizar? La respuesta es que debes sincronizar los objetos que deseas bloquear, es decir, entre múltiples subprocesos. En el problema productor-consumidor, es la cola del búfer la que debe sincronizarse.

2. Siempre llame a esperar y notificar en un bucle, no en una declaración If.

Dado que la espera siempre se llama en un contexto sincronizado y se llama en un objeto que es utilizado por múltiples subprocesos, lo siguiente que hay que recordar es que la espera siempre se debe llamar en un bucle while en lugar de en. una declaración if porque el hilo espera bajo condiciones específicas, es decir, "esperar y notificar" en el ejemplo. Debido a que el subproceso espera bajo condiciones específicas (en el ejemplo, "si la cola del búfer está llena, el subproceso productor debe esperar"), puede resultar intuitivo escribir una declaración if. Pero hay algunos defectos sutiles en la declaración if, y el hilo puede activarse por error incluso si no se cumple la condición. Por lo tanto, si no utiliza el bucle while nuevamente después de activar el subproceso para verificar si se cumple la condición de activación, el programa puede generar un error, por ejemplo, si el productor continúa generando datos cuando el búfer está lleno, o el El consumidor comienza a enviar datos cuando el búfer está vacío. Así que recuerde, use siempre esperar en un bucle while, ¡no una declaración if!

3. Si las condiciones no han cambiado y la notificación de activación de notificación se emite antes de llamar a la espera, no se garantiza que el hilo se despierte, lo que puede causar un problema de interbloqueo.