我有一个Spring Boot应用程序,我有一个@Service
,它很重,可以执行0.5到5秒。如果执行时间超过1秒并回退为回退方法,我希望它停止执行。
/// entry point
public String longLatingMethod(Payload payload) {
/// long lasting operation that can take up to 5 seconds
return value;
}
// I want this method to be executed if `longLatingMethod` takes more than 1 second to execute.
public String fallbackMethod(Payload payload) {
return defaultValue;
}
现在我已经使用Hystrix
框架实现了该功能,但是由于Hystrix
已停产,因此我想知道还有什么其他库?
答案 0 :(得分:0)
您必须在某种线程中运行任务,以便您可以继续执行并等待(一定毫秒数)以使该过程完成。如果未在指定时间内完成,请中断主要任务并运行备份任务。请注意,您的主要任务将必须检查它是否被中断,阻塞操作通常已经对此进行了检查,并且在中断时将停止阻塞。
public static void main(String[] args){
Thread t = new Thread(() -> {
// your long running task here...
System.out.println("running primary task");
// simulate it taking too long...
// will need to check if it is interrupted if you want to terminate it sooner
try {
Thread.sleep(60000);
} catch (InterruptedException e) {
System.out.println("primary task interrupted");
}
});
t.start();
// one second threshold
try { t.join(1000); } catch (Exception e) {}
if (t.isAlive()) {
// if the primary task is still running interrupt it
t.interrupt();
// run your backup task
System.out.println("running backup task");
// ...
System.out.println("backup task completed");
} else {
System.out.println("primary task completed");
}
}
输出:
running primary task
running backup task
primary task interrupted
backup task completed
答案 1 :(得分:0)
您可以使用Future尤其是方法V get(long timeout, TimeUnit unit)
:
在必要的情况下最多等待给定时间以完成计算,然后检索其结果(如果有)。
并按以下方式使用它:
<?php
if(have_posts()){
while(have_posts()){
the_post();
//echo wp_count_posts();
?>
<h1><?php echo the_title(); ?></h1>
<h3><?php echo the_content();?></h3>
<hr>
<?php
}
}
?>
请注意,如果您不定期修改某个方法是否完成检查,就无法停止该方法的执行,但是通常无法执行,例如,您是否要求对数据库进行查询,查询需要5秒钟,您无法在5秒钟之前检查。
答案 2 :(得分:-1)
不确定是不是最佳解决方案,请检查以下问题:Java: set timeout on a certain block of code?
然后在超时捕获块中添加回退
final Runnable stuffToDo = new Thread() {
@Override
public void run() {
/* Do stuff here. */
}
};
final ExecutorService executor = Executors.newSingleThreadExecutor();
final Future future = executor.submit(stuffToDo);
executor.shutdown(); // This does not cancel the already-scheduled task.
try {
future.get(1, TimeUnit.Seconds);
}
catch (InterruptedException ie) {
/* Handle the interruption. Or ignore it. */
}
catch (ExecutionException ee) {
/* Handle the error. Or ignore it. */
}
catch (TimeoutException te) {
return fallbackMethod(payload);
}