webentwicklung-frage-antwort-db.com.de

So starten Sie einen Thread nach einer festgelegten Zeitverzögerung in Java

Ich habe eine Methode in ServletContextListener als Thread aufgerufen. Jetzt muss ich den Thread für 1 Minuten verzögern und dann die im Thread aufgerufene Methode ausführen, aber ich bin nicht dazu in der Lage, da ich in diesem Bereich sehr neu bin ...

Hier ist mein 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();

}

Bitte helfen Sie mir ... Vielen Dank im Voraus ..

22
Adi

Um dies richtig zu machen, müssen Sie einen ScheduledThreadPoolExecutor verwenden und die Funktion schedule wie folgt verwenden:

final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(NUM_THREADS);
executor.schedule(new Runnable() {
  @Override
  public void run() {
    captureCDRProcess();
  }
}, 1, TimeUnit.MINUTES);

Thread.sleep ist not nicht der richtige Weg, weil es nicht garantiert, dass es nach einer Minute wieder aufwacht. Je nach Betriebssystem und Hintergrundaufgaben können es 60 Sekunden, 62 Sekunden oder 3 Stunden sein, während der obige Scheduler tatsächlich die richtige Betriebssystemimplementierung für die Planung verwendet und daher wesentlich genauer ist.

Darüber hinaus bietet dieser Scheduler verschiedene flexible Möglichkeiten, um Aufgaben zu planen, z. B. mit fester Rate oder fester Verzögerung.

Edit: Dieselbe Lösung mit der neuen Java8-Lamda-Syntax:

final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(NUM_THREADS);
executor.schedule(() -> captureCDRProcess(), 1, TimeUnit.MINUTES);
44
TwoThe

Oder Sie können die Erstellung des Threads mit Timer und TimerTask verzögern:

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

Sie können thread starten und innerhalb des Threads eine sleep-Methode für eine Minute verwenden.

2
Preetygeek

Schauen Sie sich Thread.sleep() an. Fügen Sie es der Laufmethode des neuen Threads hinzu, damit er die benötigte Zeit einschlafen kann, bevor Sie sinnvolle Arbeit erledigen.

2
Tarmo R

ScheduledThreadPoolExecutor hat diese Fähigkeit, ist aber ziemlich schwergewichtig.

Hier ist eine einfache Implementierung mit einem Test (Signatur nahe an 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();
    }
}

Prüfung:

@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