我希望在启动我的网络服务之后运行一个进程,然后每隔30分钟左右运行一次(我现在以较小的延迟测试它,只是为了查看它是否有效),但是我的进程永远不会跑一次。我做错了什么?
这是我的代码:
@WebListener
public class SchedulerService implements ServletContextListener{
@Autowired
UpdateSubscriberService updateSubscriberService;
ScheduledExecutorService scheduledExecService;
public SchedulerService(){
scheduledExecService = Executors.newSingleThreadScheduledExecutor();
}
@Override
public void contextDestroyed(ServletContextEvent arg0) {
scheduledExecService.shutdown();
}
@Override
public void contextInitialized(ServletContextEvent arg0) {
scheduledExecService.scheduleWithFixedDelay(new Runnable(){
@Override
public void run() {
Date date = new Date(System.currentTimeMillis());
System.out.println("Running scheduled update check " + date.toString());
updateSubscriberService.checkForUpdates();
}
}, 60, 30, TimeUnit.SECONDS);
}
}
答案 0 :(得分:11)
run
try catch
代码
只是一个猜测:抛出异常。如果遇到异常,ScheduledExecutorService
会静默停止。
run
方法的代码应始终被try-catch包围,以处理和吸收任何抛出的异常。
@Override
public void run() {
try { // Let no Exception reach the ScheduledExecutorService.
Date date = new Date(System.currentTimeMillis());
System.out.println("Running scheduled update check " + date.toString());
updateSubscriberService.checkForUpdates();
} catch ( Exception e ) {
System.out.println( "ERROR - unexpected exception" );
}
}
run
方法采取婴儿步骤。从run
方法开始,除了System.out.println
之外什么都不做。
答案 1 :(得分:0)
即使在最后一次运行尚未完成的情况下,即使代码始终每隔几秒运行一次(如果管理不当,这很危险),您也可以启动您的进程位于计时器内的其他线程中。这是示例代码。
ScheduledExecutorService scheduledExecService = newSingleThreadScheduledExecutor();
scheduledExecService.scheduleWithFixedDelay(new Runnable()
{
@Override
public void run()
{
// This should be in a try-catch because any error here
// will stop the recurrence
try
{
// The timer will only repeat if the last run is finished. So
// we put each new process in a different thread than the timer
// itself, so the last timer call "finishes" as soon as the process
// leaves the timer's thread.
Thread t = new Thread(new Runnable()
{
public void run()
{
try
{
android.os.Process.setThreadPriority(Process.THREAD_PRIORITY_BACKGROUND);
MyProcessThatShouldRunEverySoManySecondsNoMatterWhat();
}
catch (Exception erTimerThread)
{
Log.e("Error", erTimerThread.toString());
}
}
});
t.setPriority(2);
t.start();
}
catch (Exception erTimer)
{
Log.e("Error", erTimer.toString());
}
}
}, 0, 60, java.util.concurrent.TimeUnit.SECONDS);