2012-06-08 35 views
6

Estoy ejecutando una aplicación web en el servidor de aplicaciones Jboss y estoy tratando de implementar una respuesta base de eventos del servidor.wait() en Servlet throws Excepción

Para lograr eso estoy usando .wait() y .notify() en la clase servlets. Básicamente hay una solicitud Ajax, el servlet bloquea con wait hasta que haya un evento en el servidor y si es así notify se activa en el servlet.

El problema es cuando no esperar (1000 * 60) en el Servlet me sale:

Servlet.service() for servlet ProcessesServlet threw exception: java.lang.IllegalMonitorStateException 

¿Es incluso posible hacer una espera() en una clase HttpServlet?

Respuesta

7

Antes de esperar en un objeto, debe asumir la propiedad.

Esto generalmente se hace con una instrucción sincronizada.

synchronized (obj) { 
     try { 
      obj.wait(someTime); 
     } catch (Throwable e) { 
      e.printStackTrace(); 
     } 
    } 
+0

y debo hacer lo mismo antes de notificarme? –

+0

[sí] (http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Object.html#notify()) –

+0

hay algo que no entiendo ... si tomar posesión con el hilo que llama a .wait usando el bloque sincronizado, ¿cómo puedo tomar posesión del hilo que llamará a .notify? Me refiero a que el primer bloque sincronizado no finalizó debido a la declaración de espera ... ¿correcto? ¿No habrá exclusión mutua? –

1

Como dijo Dystroy, debe tener un bloqueo en un objeto para llamar "esperar" en él. Si, por alguna razón, no puede o no quiere hacer eso (tal como el mismo método ejecutan al mismo tiempo tratando de obtener un bloqueo en el mismo objeto), puede utilizar:

try{ 
    Thread.sleep(time); 
} catch (Exception ex){ 
    Thread.interrupted(); 
} 

o declarar un nuevo objeto para obtener un candado

2

No puede poner wait (...) en servlet porque doPost, doGet, ... no son métodos sincronizados.

puede poner en espera solo en método o bloque sincronizado. Para que pueda poner un bloque sincronizado y poner la espera en él. Como a continuación -

synchronized (object) { 
     try { 
      object.wait(1000*60); 
     } catch (Throwable ex) { 
      ex.printStackTrace(); 
     } 
    } 
2

A la respuesta aceptada le falta una condición. Cada vez que espere, siempre debe verificar una condición para protegerse de la activación espuria. Básicamente, se espera que la espera vuelva normalmente en todos los casos que dice que lo hará. También puede regresar sin motivo aparente. Debe seguir el patrón del Javadoc. No recomendaría atrapar a Throwable aquí o casi en cualquier parte. En cambio, atrapa solo la Excepción interrumpida. Además, debe asegurarse de que la verificación de condición sea segura para la ejecución de subprocesos. Así, por ejemplo, usted podría hacer lo siguiente:

private boolean condition; 
private Object lock = new Object(); 
private long timeout = 1000; 

public void conditionSatisfied() { 
    synchronized (lock) { 
     condition = true; 
     lock.notify(); 
    } 
} 

public void awaitCondition() { 
    synchronized (lock) { 
     while (!condition) { 
      try { 
       lock.wait(timeout); 
      } catch (InterruptedException e) { 
       // Probably throw some application specific exception 
      } 
     } 
     // Perform action appropriate to condition 
    } 
} 

Se dará cuenta de que usted está esperando en un bucle. El tiempo de espera solo significa que espera en intervalos de hasta el valor de tiempo de espera. Si desea establecer un límite general en su tiempo de espera, debe tener en cuenta la hora actual fuera del ciclo y verificarlo después de cada espera.

Cuestiones relacionadas