J'ai appelé une méthode dans ServletContextListener en tant que fil .. Maintenant, selon mon besoin, je dois retarder le fil pendant 1 minutes, puis commencer à exécuter la méthode appelée dans le fil mais je ne suis pas en mesure de le faire car je suis très nouveau dans ce ...
Voici mon code ...
public class Startup implements ServletContextListener {
@Override
public void contextDestroyed(ServletContextEvent sce) {
}
public void contextInitialized(ServletContextEvent sce) {
// Do your startup work here
System.out.println("Started....");
//captureCDRProcess();
new Thread(new Runnable() {
@Override
public void run() {
captureCDRProcess();
}
}).start();
}
S'il vous plaît aidez-moi ... Merci d'avance ..
Pour faire cela correctement, vous devez utiliser un ScheduledThreadPoolExecutor et utiliser la fonction schedule comme ceci:
final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(NUM_THREADS);
executor.schedule(new Runnable() {
@Override
public void run() {
captureCDRProcess();
}
}, 1, TimeUnit.MINUTES);
Thread.sleep est le chemin à suivre pas, car il ne garantit pas qu'il se réveille au bout d'une minute. Selon le système d'exploitation et les tâches d'arrière-plan, cela peut prendre 60 secondes, 62 secondes ou 3 heures, tandis que le planificateur ci-dessus utilise la mise en œuvre de système d'exploitation correcte pour la planification et est donc beaucoup plus précis.
De plus, cet ordonnanceur offre plusieurs autres moyens flexibles de planifier des tâches, par exemple à taux fixe ou à délai fixe.
Edit: Même solution en utilisant la nouvelle syntaxe Java8 Lamda:
final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(NUM_THREADS);
executor.schedule(() -> captureCDRProcess(), 1, TimeUnit.MINUTES);
Ou vous pouvez retarder la création du fil avec Timer et TimerTask:
public void contextInitialized() {
// Do your startup work here
System.out.println("Started....");
Timer timer = new Timer();
TimerTask delayedThreadStartTask = new TimerTask() {
@Override
public void run() {
//captureCDRProcess();
//moved to TimerTask
new Thread(new Runnable() {
@Override
public void run() {
captureCDRProcess();
}
}).start();
}
};
timer.schedule(delayedThreadStartTask, 60 * 1000); //1 minute
}
Vous pouvez démarrer thread
et utiliser une méthode sleep
pendant une minute dans le thread.
Jetez un coup d'œil à Thread.sleep()
. Peut-être l'ajoutez-vous à la méthode d'exécution du nouveau thread, afin qu'il dorme le temps nécessaire avant de faire un travail significatif.
ScheduledThreadPoolExecutor
a cette capacité, mais elle est assez lourde.
Voici une implémentation simple avec un test (signature proche d'Android Handler.postDelayed () ):
public class JavaUtil {
public static void postDelayed(final Runnable runnable, final long delayMillis) {
final long requested = System.currentTimeMillis();
new Thread(new Runnable() {
@Override
public void run() {
while (true) {
try {
long leftToSleep = requested + delayMillis - System.currentTimeMillis();
if (leftToSleep > 0) {
Thread.sleep(leftToSleep);
}
break;
} catch (InterruptedException ignored) {
}
}
runnable.run();
}
}).start();
}
}
Tester:
@Test
public void testRunsOnlyOnce() throws InterruptedException {
long delay = 100;
int num = 0;
final AtomicInteger numAtomic = new AtomicInteger(num);
JavaUtil.postDelayed(new Runnable() {
@Override
public void run() {
numAtomic.incrementAndGet();
}
}, delay);
Assert.assertEquals(num, numAtomic.get());
Thread.sleep(delay + 10);
Assert.assertEquals(num + 1, numAtomic.get());
Thread.sleep(delay * 2);
Assert.assertEquals(num + 1, numAtomic.get());
}