我在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();
}
请帮助我..提前谢谢..
要正确地执行此操作,您需要使用 ScheduledThreadPoolExecutor 并使用函数 schedule,如下所示:
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);
你可以延迟使用Timer and 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
}
看看Thread.sleep()
.也许将其添加到新线程的 run 方法中,以便它在执行任何有意义的工作之前休眠所需的时间。
您可以启动thread
并在线程内部使用sleep
方法一分钟。
>ScheduledThreadPoolExecutor
有这种能力,但它相当重量级。
这是一个带有测试的简单实现(签名接近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
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());
}