Ich verwende JSP/Servlet auf Apache Tomcat. Ich muss alle 10 Minuten eine Methode ausführen. Wie kann ich das erreichen?Wie führe ich eine Hintergrund-Job-Methode in festen Intervallen aus?
Antwort
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
}
}
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 machenTimer
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.
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
- 1. generieren Permutationen von Werten in festen Intervallen
- 2. Ich führe eine * angeschlossene * Bildschirmsitzung asynchron aus
- 3. Wie kann ich eine Bildlaufleiste nur in festen Intervallen scrollen lassen?
- 4. Wie führe ich einen Seitenwechsel unter einem festen Container durch?
- 5. Wie führe ich eine Zeilensperre aus?
- 6. Wie führe ich eine bessere Kolorierungsfunktion aus?
- 7. Wie führe ich eine Qt-Anwendung aus?
- 8. Wie führe ich TopoJSON aus?
- 9. Wie führe ich eine Funktion von R aus C# aus?
- 10. Wie führe ich eine gespeicherte Prozedur aus Preparestatement aus
- 11. Wie führe ich page.render in page.evaluate aus?
- 12. Wie führe ich eine Aufgabe täglich aus Java aus?
- 13. Wie führe ich Zeichenketten in Java aus?
- 14. Wie führe ich findAndModify in Restheart aus?
- 15. Wie führe ich Bitoperationen in glsl aus?
- 16. Wie führe ich eine anonyme Funktion in TypeScript aus?
- 17. Wie führe ich eine Prozedur in einem Paket aus?
- 18. Wie führe ich eine externe Funktion in Laravel 5.2 aus?
- 19. Wie führe ich eine Konsolenanwendung in Microsoft Windows aus
- 20. Wie führe ich eine unendliche Summe numerisch in Python aus?
- 21. Wie führe ich eine geplante Aufgabe in sailsjs aus?
- 22. Wie führe ich eine willkürliche Startfunktion in einem Ringprojekt aus?
- 23. Wie führe ich eine Methode in einer MVC-Anwendung aus?
- 24. Wie führe ich eine Funktion asynchron in C++ aus?
- 25. Wie führe ich eine HEAD Anfrage in GO aus?
- 26. Wie führe ich eine bestimmte Aktivität in Android Studio aus?
- 27. Wie führe ich eine Abfrage mehrmals in PostgreSQL aus?
- 28. Wie führe ich eine Geospatial-Abfrage in Mongo aus?
- 29. Wie führe ich eine JAR-Datei in mehreren Threads aus?
- 30. Wie führe ich eine asynchrone Nachbearbeitung in CherryPy aus?
Ok ich habe ich habe es.aber von wo ich diese Methode anrufen muss. Ich muss das starten, sobald meine Anwendung –
ist [Verwenden Sie nie 'Timer' in Java EE] (http://stackoverflow.com/questions/9173132/stop-scheduled-timer-when-shutdown-tomcat/9186070#9186070). – BalusC
Danke @BalusC Ich habe das ausdrücklich in meiner Antwort erwähnt. – user1697575