¿Por qué solo se puede sincronizar esperar y notificar?

Prólogo

esperar y notificar debe estar en el bloque sincronizado, de lo contrario se lanzará una IllegalMonitorStateException.

Razón

Ejemplo de código

class BlockingQueue {
    Queue<String> buffer = new LinkedList<String>();

    public void give(String data) {
        buffer.add(data);
        notify();                   
    }

    public String take() throws InterruptedException {
        while (buffer.isEmpty())    
            wait();
        return buffer.remove();
    }
}

El problema con el ejemplo de código

Un consumidor llama a take y encuentra buffer.isEmpty.
Antes de que las llamadas del consumidor esperen, debido a la programación de la CPU, el hilo del consumidor se suspende, las llamadas del productor dan y luego notifican.
Luego, el consumidor llama a esperar (tenga en cuenta que debido a un juicio condicional incorrecto, la llamada de espera es después de notificar, que es la clave).
Si desafortunadamente, el productor ya no produce mensajes después de producir un mensaje, entonces el consumidor se quedará colgado todo el tiempo, incapaz de consumir, causando un punto muerto.

Clave

Siempre haga dar / notificar y tomar / esperar operaciones atómicas. esperar / notificar es la comunicación entre hilos. Tienen una condición de carrera. Debemos asegurarnos de esperar solo cuando se cumplan las condiciones. En otras palabras, si no se agrega ningún bloqueo, la condición de espera puede no cumplirse cuando se llama a esperar (como se indicó anteriormente). Debido a la espera en condiciones incorrectas, es posible que nunca se notifique, por lo que debemos forzar la espera / notificación sincronizada.

Supongo que te gusta

Origin www.cnblogs.com/jichi/p/12694173.html
Recomendado
Clasificación