web-dev-qa-db-fra.com

Comment démarrer un thread après le délai spécifié en java

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 ..

22
Adi

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);
44
TwoThe

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
}
9
Melquiades

Vous pouvez démarrer thread et utiliser une méthode sleep pendant une minute dans le thread.

2
Preetygeek

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.

2
Tarmo R

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