EDIT: Ahora estoy seguro de que el problema está relacionado con el while (true)
lazo que sostiene todos los otros comandos como he comentado a cabo y los despliega aplicaciones sin la excepción adjunta. No estoy seguro de cuánto es importante pero mi ServletContextListener
aplicación se ve así:Cómo crear un hilo que corre todo el tiempo que mi aplicación se está ejecutando
public class BidPushService implements ServletContextListener{
public void contextInitialized(ServletContextEvent sce) {
//Some init code not relevant, omitted for clarity
BidPushThread t= new BidPushThread();
t.setServletContext(sce.getServletContext());
t.run();
}
Así que ahora el hilo se ejecute cuando se despliega la aplicación, pero debido a que el bucle while
se comenta que no tiene significado real .
Necesito tener una secuencia de ejecución en segundo plano cuando se carga mi aplicación y constantemente (sin tiempo de espera) verificar una cierta cola de objetos. Por supuesto, una vez que hay objetos, "los cuida" y luego continúa revisando la cola.
Actualmente, estoy implementando la interfaz ServletContextListener
y me llaman cuando se carga la aplicación. En él, hago algunas cosas de mantenimiento y comienzo un hilo que heredé de java.lang.Thread
.
Aquí es donde comienza mi problema (o eso creo). En mi método run()
, tengo un
while (true) {
//some code which doesn't put the thread to sleep ever
}
Cuando intento de desplegar mi aplicación al servidor consigo un java.util.concurrent.TimeOutException
. ¿Qué estoy haciendo mal?
¿No puedo tener un hilo que esté siempre en ejecución? Cuando se elimina la aplicación, ese hilo es detenido por el evento correspondiente en mi ServletContextListener
.
Realmente necesito algo que siga revisando la cola sin demora.
¡Muchas gracias por cualquier ayuda!
Editar: Este es el seguimiento de la pila
GlassFish: deploy is failing=
java.util.concurrent.TimeoutException
at java.util.concurrent.FutureTask$Sync.innerGet(Unknown Source)
at java.util.concurrent.FutureTask.get(Unknown Source)
at com.sun.enterprise.jst.server.sunappsrv.SunAppServerBehaviour.publishDeployedDirectory(SunAppServerBehaviour.java:710)
at com.sun.enterprise.jst.server.sunappsrv.SunAppServerBehaviour.publishModuleForGlassFishV3(SunAppServerBehaviour.java:569)
at com.sun.enterprise.jst.server.sunappsrv.SunAppServerBehaviour.publishModule(SunAppServerBehaviour.java:266)
at org.eclipse.wst.server.core.model.ServerBehaviourDelegate.publishModule(ServerBehaviourDelegate.java:948)
at org.eclipse.wst.server.core.model.ServerBehaviourDelegate.publishModules(ServerBehaviourDelegate.java:1038)
at org.eclipse.wst.server.core.model.ServerBehaviourDelegate.publish(ServerBehaviourDelegate.java:872)
at org.eclipse.wst.server.core.model.ServerBehaviourDelegate.publish(ServerBehaviourDelegate.java:708)
at org.eclipse.wst.server.core.internal.Server.publishImpl(Server.java:2690)
at org.eclipse.wst.server.core.internal.Server$PublishJob.run(Server.java:272)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)
Mi Código:
public class BidPushThread extends Thread {
private ServletContext sc=null;
@Override
public void run() {
if (sc!=null){
final Map<String, List<AsyncContext>> aucWatchers = (Map<String, List<AsyncContext>>) sc.getAttribute("aucWatchers");
BlockingQueue<Bid> aucBids = (BlockingQueue<Bid>) sc.getAttribute("aucBids");
Executor bidExecutor = Executors.newCachedThreadPool();
final Executor watcherExecutor = Executors.newCachedThreadPool();
while(true)
{
try // There are unpublished new bid events.
{
final Bid bid = aucBids.take();
bidExecutor.execute(new Runnable(){
public void run() {
List<AsyncContext> watchers = aucWatchers.get(bid.getAuctionId());
for(final AsyncContext aCtx : watchers)
{
watcherExecutor.execute(new Runnable(){
public void run() {
// publish a new bid event to a watcher
try {
aCtx.getResponse().getWriter().print("A new bid on the item was placed. The current price "+bid.getBid()+" , next bid price is "+(bid.getBid()+1));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
};
});
}
}
});
} catch(InterruptedException e){}
}
}
}
public void setServletContext(ServletContext sc){
this.sc=sc;
}
}
Lo siento por el desorden formato, pero para la vida de mi "código de guión por 4 espacios" simplemente no funciona para mí Editar: Lea sobre 'BlockingQueue' y lo implementé, pero todavía estoy obteniendo la misma excepción y el mismo stack stack. cambiado el código anterior para reflejar el uso de 'BlockingQueue'
Necesitará darnos el rastro de la pila de la excepción – skaffman
Por favor muestre su código. Hay muy pocas clases en la API de Java que lanzan la excepción que está recibiendo, y su uso no coincide con la descripción que ha proporcionado. – SingleShot
Definitivamente debería usar una cola de bloqueo. JavaDocs para http://java.sun.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html tiene código de ejemplo. –