EDIT: Je suis maintenant sûr que le problème est lié à la boucle while (true)
maintenant toutes les autres commandes comme je l'ai commenté et l'application déploie sans l'exception jointe. Je ne sais pas combien il est important, mais ma mise en œuvre ServletContextListener
ressemble à ceci:Comment créer un thread qui s'exécute tout le temps que mon application est en cours
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();
}
Alors maintenant, le fil est exécuté lorsque l'application est déployée, mais parce que la boucle while
est commenté, il n'a pas de sens réel .
Je dois avoir un thread en arrière-plan lorsque mon application se charge et constamment (sans timeout) vérifier une certaine file d'attente pour les objets. Bien sûr, une fois qu'il y a des objets, il "prend soin d'eux" et continue ensuite à vérifier la file d'attente.
Actuellement, j'implémente l'interface ServletContextListener
et on m'appelle quand l'application se charge. Dans celui-ci, je fais quelques choses de maintenance et commence un fil dont j'ai hérité de java.lang.Thread
.
Voici où commence mon problème (ou je pense). Dans ma méthode run()
, j'ai un
while (true) {
//some code which doesn't put the thread to sleep ever
}
Lorsque je tente de déployer mon application sur le serveur je reçois un java.util.concurrent.TimeOutException
. Qu'est-ce que je fais de mal?
Impossible d'avoir un thread qui est toujours en cours d'exécution? Lorsque l'application est supprimée, ce thread est arrêté par l'événement correspondant dans mon ServletContextListener
.
J'ai vraiment besoin de quelque chose qui continue à vérifier la file d'attente sans délai.
Merci beaucoup pour toute aide!
Edit: Ceci est la trace de la pile
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)
Mon 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;
}
}
Désolé pour le désordre de mise en forme, mais pour la vie de mon "code tiret par 4 espaces" ne fonctionne pas pour moi Editer: Lire à propos de 'BlockingQueue' et l'implémenter, mais je reçois toujours la même exception et trace de la pile. modifié le code ci-dessus pour tenir compte de l'utilisation de « BlockingQueue »
Vous devrez nous donner la trace de la pile de l'exception – skaffman
Veuillez montrer votre code. Il y a très peu de classes dans l'API Java qui lancent l'exception que vous recevez, et leur utilisation ne correspond pas à la description que vous avez fournie. – SingleShot
Vous devriez certainement utiliser une file d'attente de blocage. Les JavaDocs pour http://java.sun.com/javase/6/docs/api/java/util/concurrent/BlockingQueue.html ont un exemple de code. –