java - 如何在指定的时间延迟后启动线程

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19999231/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 22:11:02  来源:igfitidea点击:

How to start a thread after specified time delay in java

javamultithreadingservletcontextlistener

提问by Adi

I have called a method in ServletContextListener as thread ..Now as per my need i have to delay the thread for 1 minutes and then start executing the method called in the thread but i am not able to do that as i am very new in this...

我在 ServletContextListener 中调用了一个方法作为线程..现在根据我的需要,我必须将线程延迟 1 分钟,然后开始执行线程中调用的方法,但我无法做到这一点,因为我对此很陌生...

Here is my 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();

}

Please help me .. Thanks in advance..

请帮助我.. 提前致谢..

回答by Prettygeek

You can start threadand inside the thread use sleepmethod for one minute.

您可以开始thread和内部线程使用sleep方法一分钟。

回答by Tarmo R

Have a look at Thread.sleep(). Maybe add it to the new thread's run method, so that it sleeps the needed time before doing any meaningful work.

看看Thread.sleep()。也许将它添加到新线程的 run 方法中,以便它在做任何有意义的工作之前休眠所需的时间。

回答by Melquiades

Or you can delay creating the thread with Timer and TimerTask:

或者您可以使用 Timer 和 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
}

回答by TwoThe

To do this properly, you need to use a ScheduledThreadPoolExecutor and use the function schedulelike this:

要正确执行此操作,您需要使用 ScheduledThreadPoolExecutor 并使用如下功能调度

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

Thread.sleep is notthe way to go, because it does not guarantee that it wakes up after a minute. Depending on the OS and the background tasks, it could be 60 seconds, 62 seconds or 3 hours, while the scheduler above actually uses the correct OS implementation for scheduling and is therefore much more accurate.

Thread.sleep不是办法,因为它不保证一分钟后醒来。根据操作系统和后台任务,它可能是 60 秒、62 秒或 3 小时,而上面的调度程序实际上使用正确的操作系统实现进行调度,因此更加准确。

In addition this scheduler allows several other flexible ways to schedule tasks like at a fixed rate or fixed delay.

此外,此调度程序允许使用其他几种灵活的方式来调度任务,例如以固定速率或固定延迟。

Edit:Same solution using the new Java8 Lamda syntax:

编辑:使用新的 Java8 Lamda 语法的相同解决方案:

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

回答by AlikElzin-kilaka

ScheduledThreadPoolExecutorhas this ability, but it's quite heavyweight.

ScheduledThreadPoolExecutor有这个能力,但是相当的重量级。

Here's a simple implementation with a test (signature close to Android's Handler.postDelayed()):

这是一个带有测试的简单实现(签名接近 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();
    }
}

Test:

测试:

@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());
}