2013-04-03 3 views

Antwort

3

mehr lesen ScheduledExecutorService hat es von einem ServletContextListener

public class MyContext implements ServletContextListener 
{ 
    private ScheduledExecutorService sched; 

    @Override 
    public void contextInitialized(ServletContextEvent event) 
    { 
     sched = Executors.newSingleThreadScheduledExecutor(); 
     sched.scheduleAtFixedRate(new MyTask(), 0, 10, TimeUnit.MINUTES); 
    } 

    @Override 
    public void contextDestroyed(ServletContextEvent event) 
    { 
     sched.shutdownNow(); 
    } 
} 

auch initiiert werden, können Sie versuchen, die Java Timer von einem ServletContextListener verwenden, aber es ist nicht in einem Java EE Container empfohlen, da es die Kontrolle über das wegnimmt Fädeln Sie Ressourcen aus dem Container ein. (Die erste Option mit ScheduledExecutorService ist der Weg zu gehen).

Timer timer = new Timer("MyTimer"); 
MyTask t = new MyTask(); 

//Second Parameter is the specified the Starting Time for your timer in 
//MilliSeconds or Date 

//Third Parameter is the specified the Period between consecutive 
//calling for the method. 

timer.schedule(t, 0, 1000*60*10); 

Und MyTask die TimerTask implementiert, ist eine Klasse, die die Runnable-Schnittstelle implementiert, so dass Sie die run-Methode mit Ihrem Code außer Kraft zu setzen haben:

class MyTask extends TimerTask 
{ 
    public void run() 
    { 
    // your code here 
    } 
} 
+0

Ok ich habe ich habe es.aber von wo ich diese Methode anrufen muss. Ich muss das starten, sobald meine Anwendung –

+2

ist [Verwenden Sie nie 'Timer' in Java EE] (http://stackoverflow.com/questions/9173132/stop-scheduled-timer-when-shutdown-tomcat/9186070#9186070). – BalusC

+0

Danke @BalusC Ich habe das ausdrücklich in meiner Antwort erwähnt. – user1697575

10

Wie Sie auf Tomcat sind, das nur eine Barebones Servletcontainer, können Sie nicht EJBs @Schedule für diese verwenden, die von Java EE-Spezifikation empfohlen wird. Ihre beste Wette ist dann die von Java 1.5 java.util.concurrent Paket. Sie können dies auslösen mit Hilfe eines ServletContextListener wie folgt:

@WebListener 
public class BackgroundJobManager implements ServletContextListener { 

    private ScheduledExecutorService scheduler; 

    @Override 
    public void contextInitialized(ServletContextEvent event) { 
     scheduler = Executors.newSingleThreadScheduledExecutor(); 
     scheduler.scheduleAtFixedRate(new SomeTask(), 0, 10, TimeUnit.MINUTES); 
    } 

    @Override 
    public void contextDestroyed(ServletContextEvent event) { 
     scheduler.shutdownNow(); 
    } 

} 

wo die SomeTask Klasse sieht wie folgt aus:

public class SomeTask implements Runnable { 

    @Override 
    public void run() { 
     // Do your job here. 
    } 

} 

Wenn Sie tatsächlich eine echte Java EE-Container mit EJB-Unterstützung verwendet haben und alle auf em (wie Glassfish, JBoss AS, TomEE usw.), dann könnten Sie eine @Singleton EJB mit einer @Schedule Methode verwenden. Auf diese Weise kümmert sich der Container selbst um das Sammeln und Zerstören von Threads. Sie brauchen, ist dann die folgende EJB:

@Singleton 
public class SomeTask { 

    @Schedule(hour="*", minute="*/10", second="0", persistent=false) 
    public void run() { 
     // Do your job here. 
    } 

} 

Beachten Sie, dass diese Art und Weise Sie transparent mit Container verwaltet Transaktionen in der üblichen Weise (@PersistenceContext usw.) fortsetzen kann, die mit nicht möglich ist ScheduledExecutorService — Sie müss um den Entity Manager manuell zu erhalten und die Transaktion manuell zu starten/zu committen/zu beenden, aber Sie hätten ohnehin ohnehin keine andere Option auf einem Barebones-Servletcontainer wie Tomcat.

Beachten Sie, dass Sie nie eine Timer in einer vermeintlich "lebenslangen" Java EE-Webanwendung verwenden sollten. Es hat die folgenden Hauptprobleme, die es nicht geeignet für den Einsatz in Java EE (zitiert aus Java Concurrency in Practice) macht:

  • Timer ist empfindlich gegenüber Veränderungen in dem Systemtakt, ScheduledExecutorService nicht.
  • Timer hat nur einen Ausführungsthread, daher kann eine lang andauernde Task andere Tasks verzögern. ScheduledExecutorService kann mit einer beliebigen Anzahl von Threads konfiguriert werden.
  • Alle Laufzeitausnahmen, die in einem TimerTask geworfen werden, töten diesen einen Thread und machen Timer tot, d. H. Geplante Tasks werden nicht mehr ausgeführt (bis Sie den Server neu starten). ScheduledThreadExecutor fängt nicht nur Laufzeitausnahmen ab, sondern lässt Sie auch behandeln, wenn Sie möchten. Die Aufgabe, die die Ausnahme ausgelöst hat, wird abgebrochen, andere Aufgaben werden jedoch weiterhin ausgeführt.
+0

Große Antwort, danke @BalusC. Eine Frage: Wie würde ich den Scheduler ändern, wenn ich das Intervall zwischen den Anrufen ändern möchte? z.B. Ich habe eine'int frequency', die vom Benutzer in webgui eingestellt werden kann und die Zeit zwischen den Läufen in Sekunden darstellt. – Gewure

Verwandte Themen