Frage

EDIT: Ich bin jetzt sicher, dass das Problem der Beziehung steht     while (true) Schleife alle anderen Befehle halten, wie ich es kommentiert habe und die Anwendung setzt, ohne die beigefügten Ausnahme. Ich bin nicht sicher, wie viel es ist wichtig, aber meine ServletContextListener Implementierung sieht wie folgt aus:

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();
}

So, jetzt der Thread ausgeführt wird, wenn die Anwendung bereitgestellt wird, sondern weil die while Schleife kommentiert wird es hat keine wirkliche Bedeutung.

Ich brauche einen Thread im Hintergrund laufen zu lassen, wenn meine Anwendung geladen und ständig (ohne Timeout) eine bestimmte Warteschlange für Objekte überprüfen. Natürlich, wenn es Gegenstände gibt, es „kümmert sich um sie“ und geht dann in die Warteschlange zu überprüfen.

Derzeit bin ich der Umsetzung der ServletContextListener Schnittstelle und ich werden, wenn die App Lasten genannt. Darin ich habe ein paar Dinge Wartung und einen Thread starten, die ich von java.lang.Thread geerbt.

Hier ist, wo mein Problem beginnt (oder so glaube ich). In meiner run() Methode, ich habe ein

while (true) {
    //some code which doesn't put the thread to sleep ever
}

Wenn ich versuche, meine App an den Server zu implementieren erhalte ich eine java.util.concurrent.TimeOutException. Was mache ich falsch?

Kann ich nicht ein Gewinde, das immer läuft? Wenn der App entfernt wird, dass Faden durch das entsprechende Ereignis in meinem ServletContextListener gestoppt wird.

ich wirklich etwas tun müssen, die auf die Überprüfung der Warteschlange ohne Verzögerung hält.

Vielen Dank für jede Hilfe!

Edit: Dies ist der Stack-Trace

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)

Mein 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;
    }
}

Sorry für die Formatierung Chaos, sondern für das Leben meines „indent Code von 4 Leerzeichen“ funktioniert einfach nicht für mich Edit: Lesen Sie mehr über ‚Blocking‘ und umgesetzt, aber ich bin immer noch genau die gleiche Ausnahme und Stack-Trace zu bekommen. geändert, um den oben genannten Code die Verwendung von ‚Blocking‘

widerzuspiegeln
War es hilfreich?

Lösung

Ihr Code nicht einen neuen Thread startet, läuft die Schleife im selben Thread und das ist, warum Sie einen Timeout-Fehler bekommen, wenn im Einsatz.

Um einen Thread starten Sie den Start-Methode aufrufen müssen, nicht die run-Methode.

public void contextInitialized(ServletContextEvent sce) {   
//Some init code not relevant, omitted for clarity
  BidPushThread t= new BidPushThread();
  t.setServletContext(sce.getServletContext());
  t.start();// run();
}

Andere Tipps

setDaemon

  

Zusammenfassung:

     
      
  • Marks dieses Thema entweder als Daemon-Thread oder ein Benutzer-Thread. Das   Java Virtual Machine beendet, wenn die   nur Threads laufen alle Daemon   Threads.
  •   
  • Diese Methode muss aufgerufen werden, bevor der Thread gestartet wird.
  •   
  • Diese Methode ruft zuerst die Methode checkaccess dieses Threads
      ohne Argumente. Dies kann dazu führen   Werfen eines Security (im
      aktuelle Thread).
  •   

Themen

  

Zusammenfassung: In vielen Fällen, was wir wirklich   wollen, ist Hintergrund-Threads erstellen   das tut einfach, periodische Aufgaben in einem   Anwendung. Die setDaemon () Methode   kann verwendet werden, um ein Thema als markieren   Daemon-Thread, die getötet werden sollten,   und verworfen, wenn keine andere   Anwendungsthreads bleiben. Normalerweise,   das Java-Interpreter läuft weiter   bis alle Threads abgeschlossen haben. Aber   Wenn Daemon-Threads sind die einzige   noch am Leben Fäden, der Dolmetscher   verlassen wird.

Dies wäre eine sehr schlechte Idee. Sie würden eine 100% CPU-Last, ohne einen guten Grund führen.

Die richtige Lösung ist wahrscheinlich, den Faden zu blockieren, wenn die Warteschlange leer ist. Dies ist trivialerweise mit einem BlockingQueue implementiert.

Can't I have a thread which is always running? When the app is removed, 
that thread is stopped by the corresponding event in my ServletContextListener.

„Das Gewinde wird gestoppt“? Wie? Es gibt keine Abbruchbedingung in Ihrer while (true) {...} Schleife. Wie werden Stoppen Sie es? Sind Sie mit dem Thread.stop () -Methode? Das ist unsicher und wurde als veraltet Weg zurück in Java 1.1

Wenn Sie setDaemon verwenden (true), wird der Thread aktiv bleiben, nachdem Sie die Web-App mit Ihrem App-Server-Management-Tools gestoppt haben. Dann, wenn Sie die Web-App neu starten, werden Sie einen anderen Thread bekommen. Selbst wenn Sie die Web-App deimplementieren versuchen, bleiben der Thread läuft und wird die gesamte Web-App ist Garbage Collection verhindern. Dann die nächste Version Umschichtung gibt Ihnen eine zusätzliche Kopie von allem, was im Speicher.

Wenn Sie eine Ausgangsbedingung für die Schleife (z.B. InterruptedException oder eine flüchtige „StopNow“ boolean), können Sie dieses Problem vermeiden.

Werfen Sie einen Blick auf java.langThread.setDaemon () -Methode, kann es das, was Sie benötigen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top