2012-01-11 8 views
5

considere el siguiente código: -¿Por qué el método de notificación debe estar dentro de un bloque sincronizado?

class CalculateSeries implements Runnable{ 
    int total; 
    public void run(){ 
     synchronized(this){       // *LINE 1* 
      for(int i = 1; i <= 10000; i++) { 
       total += i; 
      } 

      notify(); //Notify all the threads waiting on this instance of the class to wake up 
     } 
    } 
} 

Otra clase está esperando en una instancia de esta clase por conseguir el bloqueo en el interior de un bloque sincronizado. Pero si no guardo el código en el método de ejecución en un bloque sincronizado, entonces obtengo IllegalMonitorStateException.

notify() debe significar dar señal a todos los hilos en espera. Entonces, ¿por qué debería estar dentro del bloque sincronizado?

+3

notificar no notifica todos los hilos en espera. Notifica ** un ** hilo esperando. –

+0

@JBNizet Sí. Es verdad. notify notificará solo a uno de todos los hilos elegibles. – whitehat

Respuesta

4

notify() debería significar dar señal a todos los hilos en espera.

En realidad, no. Señala uno hilo de espera elegido arbitrariamente. notifyAll() los señala a todos.

¿Entonces por qué debería estar dentro del bloque sincronizado?

Porque la espera no ocurre por sí misma. Verifica una condición y si no se cumple, espera hasta que alguien le diga que puede cumplirse (luego, vuelva a verificar). Sin sincronización, tendría condiciones de carrera entre verificar la condición y realmente esperar.

+2

Esto explica por qué 'wait()' debe estar dentro de 'synchronized', pero no' notify() '. Tenga en cuenta que, por ejemplo, [en la API de C++, esto se desaconseja explícitamente] (http://en.cppreference.com/w/cpp/thread/condition_variable/notify_one). Entonces deja abierta la pregunta de por qué Java lo requiere. – Owen

Cuestiones relacionadas