在java中,如何使用concurrency executor future在固定时间后超时方法?
使用java并发执行器,future cancel方法不会停止当前任务 我已遵循超时解决方案并停止处理当前任务。但这并没有停止处理。 我正在用cron job试试这个。每隔30秒,我的cron作业就会被执行一次,我将超时10秒。调试在将来的取消方法中出现,但它不会停止当前任务。 多谢各位在java中,如何使用concurrency executor future在固定时间后超时方法?,java,spring-boot,concurrency,cron,Java,Spring Boot,Concurrency,Cron,使用java并发执行器,future cancel方法不会停止当前任务 我已遵循超时解决方案并停止处理当前任务。但这并没有停止处理。 我正在用cron job试试这个。每隔30秒,我的cron作业就会被执行一次,我将超时10秒。调试在将来的取消方法中出现,但它不会停止当前任务。 多谢各位 @Scheduled(cron = "*/30 * * * * *") public boolean cronTest() { System.out.println("Insid
@Scheduled(cron = "*/30 * * * * *")
public boolean cronTest()
{
System.out.println("Inside cron - start ");
DateFormat dateFormat = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
Date date = new Date();
System.out.println(dateFormat.format(date));
System.out.println("Inside cron - end ");
ExecutorService executor = Executors.newCachedThreadPool();
Callable<Object> task = new Callable<Object>() {
public Object call() {
int i=1;
while(i<100)
{
System.out.println("i: "+ i++);
try {
TimeUnit.SECONDS.sleep(1);
}
catch(Exception e)
{
}
}
return null;
}
};
Future<Object> future = executor.submit(task);
try {
Object result = future.get(10, TimeUnit.SECONDS);
} catch (Exception e)
} finally {
future.cancel(true);
return true;
}
}
预期结果为:
Inside cron - start
2019/07/25 11:09:00
Inside cron - end
i: 1
i: 2
i: 3
i: 4 ... upto i: 10
Inside cron - start
2019/07/25 11:09:30
Inside cron - end
i: 1
i: 2
i: 3 ... upto i:10
第一个问题在代码的这一部分:
catch(异常e)
{
}
当您调用future.cancel(true)时代码>您的线程正在被线程中断。中断()
这意味着当线程处于睡眠状态时,它会被唤醒并抛出被catch块捕获并忽略的InterruptedException
。要解决此问题,您必须处理此异常:
catch(中断异常e){
break;//从循环中中断
}
捕获(例外e)
{
}
第二个问题:Thread.interrupt()
可能在线程未睡眠时调用。在这种情况下,不会引发中断异常。相反,线程的中断标志被提升。你要做的是不时检查这个标志,如果它被升起,处理中断。它的基本代码如下所示:
试试看{
如果(Thread.currentThread().isInterrupted()){
打破
}
时间单位。秒。睡眠(1);
}
...
//代码的其余部分
更新:
以下是可调用的的完整代码:
Callable task=newcallable(){
公共对象调用(){
int i=1;
而(i第一个问题在代码的这一部分:
catch(异常e)
{
}
当您调用future.cancel(true);
时,您的线程将被thread.interrupt()中断
这意味着当线程处于睡眠状态时,它会被唤醒并抛出被catch块捕获并忽略的InterruptedException
。要解决此问题,必须处理此异常:
catch(中断异常e){
break;//从循环中中断
}
捕获(例外e)
{
}
第二个问题:Thread.interrupt()
可以在线程未睡眠时调用。在这种情况下,不会抛出InterruptedException
。相反,线程的interrupted标志会被提升。您需要做的是不时检查此标志,如果它被提升,则处理中断。它的基本代码如下所示:
试试看{
如果(Thread.currentThread().isInterrupted()){
打破
}
时间单位。秒。睡眠(1);
}
...
//代码的其余部分
更新:
以下是可调用的的完整代码:
Callable task=newcallable(){
公共对象调用(){
int i=1;
while(我想知道答案。我试着使用catch(TimeoutException ex){Thread.currentThread().interrupt();future.cancel(true);}catch(interruptedeexception e){Thread.currentThread().interrupt();future.cancel(true);}catch(异常e){Thread.currentThread().interrupt();future.cancel(true);}
和[参考第二条注释]。但仍然没有给出预期的结果。我所做的其他更改是:尝试{if(Thread.currentThread().isInterrupted()){Thread.currentThread().interrupt();future.cancel(true);}TimeUnit.SECONDS.sleep(1);}catch(异常e){Thread.currentThread().interrupt();future.cancel(true);}
@Interstellar,使用我在答案中提供的代码。不需要捕捉TimeoutException
并调用Thread.currentThread().interrupt();
只要中断循环一次Thread.currentThread().isInterrupted()
是真的。检查更新的答案。它与您的解决方案一起工作。我很感激。非常感谢。因此相关的问题是,我们正在更改call()中的代码若我正在调用某个外部方法,那个么我可以停止执行它而不在call()中执行任何操作吗方法?@Interstellar,你不能用Future
或ExecutorService
来实现。实际上,你不需要这样做。想象一下,如果一个线程停止并留下一些资源未释放,或者只是拥有一个锁而从不释放它,会发生什么。你的应用程序中很容易出现神秘的bug。任何多线程代码都必须如果第三方方法不这样做,你可能会认为它是一个bug。谢谢你的回答。我尝试使用<代码> catch(TimeOutExistEX){Tr.CurrnthTead().Cufft();{Thread.currentThread().interrupt();future.cancel(true);}catch(异常e){Thread.currentThread().interrupt();future.cancel(true);}
和[参考第二条注释]。但仍然没有给出预期的结果。我所做的其他更改是:尝试{if(Thread.currentThread().isInterrupted()){Thread.currentThread().interrupt();future.cancel(true);}TimeUnit.SECONDS.sleep(1);}catch(异常e){Thread.currentThread().interrupt();future.cancel(true);}
@Interstallar,使用我在答案中提供的代码。无需捕获TimeoutException
并调用Thread.currentThread().interrupt();
只要中断一次循环Thread.currentThread().isInterrupted())
是正确的。请检查更新的答案。它与您的解决方案配合使用。我非常感谢。非常感谢。因此
Inside cron - start
2019/07/25 11:09:00
Inside cron - end
i: 1
i: 2
i: 3
i: 4 ... upto i: 10
Inside cron - start
2019/07/25 11:09:30
Inside cron - end
i: 1
i: 2
i: 3 ... upto i:10