ScheduledExecutorService 只运行一次
ScheduledExecutorService only runs once
我想要一个进程 运行 在我启动我的网络服务之后,然后每隔 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);
}
}
在类似问题上查看我的更长 Answer。
用 try catch
包装 run
代码
只是猜测:抛出异常。如果遇到异常,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
.
以防万一您遇到代码必须每隔这么多秒 运行 一次的情况,即使最后一个 运行 尚未完成(这可能非常如果管理不当会很危险),您可以在计时器内的不同线程内启动您的进程。这是示例代码。
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);
我想要一个进程 运行 在我启动我的网络服务之后,然后每隔 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);
}
}
在类似问题上查看我的更长 Answer。
用 try catch
包装 run
代码
只是猜测:抛出异常。如果遇到异常,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
.
以防万一您遇到代码必须每隔这么多秒 运行 一次的情况,即使最后一个 运行 尚未完成(这可能非常如果管理不当会很危险),您可以在计时器内的不同线程内启动您的进程。这是示例代码。
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);