MODIFICA: Ora sono sicuro che il problema è correlato al ciclo while (true)
che contiene tutti gli altri comandi come ho commentato e l'applicazione distribuisce senza l'eccezione allegata. Io non sono sicuro di quanto sia importante, ma il mio ServletContextListener
applicazione si presenta così:Come creare un thread che viene eseguito sempre durante l'esecuzione dell'applicazione
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();
}
Così ora il thread viene eseguito quando l'applicazione viene distribuita, ma perché il ciclo è commentato while
non ha alcun significato reale .
Ho bisogno di avere un thread in esecuzione in background quando la mia applicazione carica e costantemente (senza un timeout) controlla una certa coda per gli oggetti. Ovviamente, una volta che ci sono degli oggetti, "si prende cura di loro" e poi continua a controllare la coda.
Attualmente sto implementando l'interfaccia ServletContextListener
e mi chiamano al caricamento dell'applicazione. In esso, eseguo alcune operazioni di manutenzione e avvio una discussione ereditata da java.lang.Thread
.
Qui è dove inizia il mio problema (o almeno così penso). Nel mio metodo run()
, ho un
while (true) {
//some code which doesn't put the thread to sleep ever
}
Quando cerco di distribuire la mia applicazione al server ottengo un java.util.concurrent.TimeOutException
. Cosa sto sbagliando?
Non è possibile avere una discussione che è sempre in esecuzione? Quando l'app viene rimossa, quella discussione viene interrotta dall'evento corrispondente nel mio ServletContextListener
.
Ho davvero bisogno di qualcosa che continui a controllare la coda senza indugio.
Grazie mille per qualsiasi aiuto!
Edit: Questa è la traccia dello stack
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)
My Code:
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;
}
}
Ci scusiamo per la confusione di formattazione, ma per la vita del mio "codice di rientro da 4 spazi" semplicemente non funziona per me Modifica: leggi "BlockingQueue" e implementalo, ma sto ancora ricevendo la stessa identica eccezione e traccia dello stack. cambiato il codice di cui sopra in modo da riflettere l'uso di 'BlockingQueue'
Avrete bisogno di darci la traccia dello stack dell'eccezione – skaffman
Si prega di mostrare il codice. Esistono pochissime classi nell'API Java che generano l'eccezione che si sta ricevendo e il loro utilizzo non corrisponde alla descrizione fornita. – SingleShot
Dovresti sicuramente usare una coda di blocco. Il JavaDocs per http://java.sun.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html ha un codice di esempio. –