Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java中如何在指定的时间延迟后启动线程_Java_Multithreading_Servletcontextlistener - Fatal编程技术网

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

java中如何在指定的时间延迟后启动线程,java,multithreading,servletcontextlistener,Java,Multithreading,Servletcontextlistener,我在ServletContextListener中调用了一个方法作为线程..现在根据我的需要,我必须延迟线程1分钟,然后开始执行在线程中调用的方法,但我不能这样做,因为我在这方面非常新 这是我的密码 public class Startup implements ServletContextListener { @Override public void contextDestroyed(ServletContextEvent sce) { } public void contextInit

我在ServletContextListener中调用了一个方法作为线程..现在根据我的需要,我必须延迟线程1分钟,然后开始执行在线程中调用的方法,但我不能这样做,因为我在这方面非常新

这是我的密码

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

}
请帮帮我。。
提前感谢。

您可以启动
线程
并在线程内部使用
睡眠
方法一分钟。

查看
线程.睡眠()。可以将其添加到新线程的run方法中,以便它在执行任何有意义的工作之前睡眠所需的时间。

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

要正确执行此操作,需要使用ScheduledThreadPoolExecutor并使用如下函数:

final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(NUM_THREADS);
executor.schedule(new Runnable() {
  @Override
  public void run() {
    captureCDRProcess();
  }
}, 1, TimeUnit.MINUTES);
Thread.sleep不是一种方法,因为它不能保证它在一分钟后醒来。根据操作系统和后台任务的不同,时间可能是60秒、62秒或3小时,而上面的调度程序实际上使用正确的操作系统实现进行调度,因此更加准确

此外,该调度器还允许其他几种灵活的方式来调度任务,如以固定速率或固定延迟

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

final ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(NUM_THREADS);
executor.schedule(() -> captureCDRProcess(), 1, TimeUnit.MINUTES);
有这种能力,但它相当重

下面是一个带有测试的简单实现(签名接近Android):

测试:


这就是我要做的,而不是延迟创建线程。@Preetygeek Martin不是OP:)线程睡眠是不安全的,因为它不能保证线程在一分钟后醒来。为了向其他读者澄清,最后的
1
TimeUnit.MINUTES
控制新线程启动前的延迟。这里的NUM_THREADS是什么,它是实例吗?@Shikhar-它是
corePoolSize
-池中要保留的线程数,即使它们是空闲的。请看我喜欢这个示例:添加一些解释,timerTask不是在循环中执行吗?根据我的经验,
Timer
创建了几个线程,这使得仅延迟执行就有点沉重。可能是
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
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());
}