Java 计时器:取消正在运行的任务
我需要创建一个异步线程,该线程运行一次,延迟2分钟,并且可以随时终止。我看到了几种可能的解决方案:Java 计时器:取消正在运行的任务,java,timer,tomcat7,scheduled-tasks,Java,Timer,Tomcat7,Scheduled Tasks,我需要创建一个异步线程,该线程运行一次,延迟2分钟,并且可以随时终止。我看到了几种可能的解决方案: ScheduledExecutorService和FutureTask允许我中断正在运行的任务,但我必须调用shutdown()来终止所有正在运行的线程,这将阻止用户,直到进程终止。此外,我还必须经常调用Thread.interrupted(),如中所述 Timer和TimerTask不需要释放正在运行的线程,但我无法中断正在运行的计时器线程(Timer.cancel()只是取消未来的调度) 有问
ScheduledExecutorService
和FutureTask
允许我中断正在运行的任务,但我必须调用shutdown()
来终止所有正在运行的线程,这将阻止用户,直到进程终止。此外,我还必须经常调用Thread.interrupted()
,如中所述Timer
和TimerTask
不需要释放正在运行的线程,但我无法中断正在运行的计时器线程(Timer.cancel()
只是取消未来的调度)感谢您使用选项1,您可以将
可能中断fRunning
参数设置为true
以取消任务
创建一个,仍然可以通过FutureTask api取消
这是一个我用来验证任务是否被取消的简单测试。我想如果您执行一些阻塞IO(网络或磁盘),工作线程可能不会中断,但我还没有测试它。如果在任务未运行时调用cancel,则所有线程都会正常停止,但如果在调用cancel时任务正在运行,则执行器将尝试终止线程
public static void main(String[] args) throws InterruptedException {
ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(2);
ScheduledFuture<?> future = executor.scheduleAtFixedRate(new Runnable() {
int i = 0;
public void run() {
int j = i++;
System.err.println("Run " + j);
try {
Thread.sleep(5000L);
} catch (InterruptedException e) {
System.err.println("Interrupted " + j);
}
}
}, 1000L, 2000L, TimeUnit.MILLISECONDS);
Thread.sleep(10000L);
System.err.println("Canceled " + future.cancel(true));
Thread.sleep(20000L);
executor.shutdownNow();
System.err.println("Finished");
}
publicstaticvoidmain(String[]args)抛出InterruptedException{
ScheduledThreadPoolExecutor executor=新的ScheduledThreadPoolExecutor(2);
ScheduledFuture future=executor.scheduleAtFixedRate(new Runnable()){
int i=0;
公开募捐{
int j=i++;
系统错误println(“运行”+j);
试一试{
线程。睡眠(5000L);
}捕捉(中断异常e){
系统错误println(“中断”+j);
}
}
},1000L,2000L,时间单位为毫秒);
线程。睡眠(10000L);
System.err.println(“已取消”+future.cancel(true));
线程。睡眠(20000L);
执行者。关机现在();
系统错误打印项次(“完成”);
}
经过一些测试和研究,FutureTask.cancel()和线程需要类似的中断处理,如中所述
private final class MyTask implements Runnable {
public void run() {
try{
for(int j=0; j<100000000; j++) {
for(int i=1; i<1000000000; i++){
if(Thread.interrupted()){ //Don't use Thread.interrupt()!
Log.debug("Thread was interrupted for" + cache);
return; //Stop doing what you are doing and terminate.
}
Math.asin(0.1565365897770/i);
Math.tan(0.4567894289/i);
}
}
}catch(Throwable e){//if exception is uncaught, the scheduler may not run again
...
}
}
}
private final类MyTask实现可运行{
公开募捐{
试一试{
对于(int j=0;j对于使用TimerTask的场景2,为什么不在调用this.cancel()之后从run()方法返回呢
这是我写的一个片段。每当工具遇到可能导致进一步执行无效的情况时,比如错误配置,我都会使用相同的技术
...
if ( count < 1 ) {
logger.error("CANCELING THREAD FOR " + host + ":" + jmxPort + "! " +
"- CONFIGURATION INCOMPLETE - DUMP_COUNT must be 1 or greater.");
this.cancel();
return;
}
...
。。。
如果(计数<1){
logger.error(“取消“+host+”的线程:“+jxport+”!”+
“-配置不完整-转储_计数必须为1或更大。”);
这个。取消();
返回;
}
...
没错,但有两个缺点。首先,如果我在线程中启动一个长进程,我必须不断地引用isInterrupted标志;其次,我必须调用shutdown来释放正在运行的线程,这将阻止用户,直到线程完成运行。ExecutorService返回的FutureTask会使您无法使用线程。根据JavaDoc,如果您为MayInterruptFrunning传递true,它将负责中断工作线程。这与Enno Shioji的回答不完全一致:我使用ScheduledFuture javaDoc的附加引用更新了我的答案,该引用明确表示可以取消计划任务。谢谢,我将对其进行测试。但这种方法仍然需要我调用ScheduledFuturedExecutorService.shutdown()最终释放线程。我不想阻止用户并等待所有线程完成运行