延时重试是什么
在许多场景下,需要通过重试几次来取到正确的值,例如 ,在通过接口申请维表数据的时候,有可能接口设置限流,所以需要重试多次来获取正确的数据。这种重试如何实现呢?
最容易想到的做法,就是通过 sleep() 休眠几秒来完成,如下所示:
public class DelayedRetryExample {
public static void main(String[] args) {
int maxRetries = 3;
int retryInterval = 1000; // 重试间隔 1000ms,即1秒
for (int i = 0; i < maxRetries; i++) {
if (performTask()) {
System.out.println("任务执行成功!");
break;
} else {
System.out.println("任务执行失败,开始第 " + (i+1) + " 次重试...");
try {
Thread.sleep(retryInterval);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
private static boolean performTask() {
// 模拟任务执行,这里简单返回 true 或 false,可根据实际情况修改
return Math.random() < 0.5; // 50% 的概率任务失败
}
}
```
## 更好的做法
sleep 这种方式,可能会造成线程被打断的问题,我们可以是同调度线程池 + 递归实现,如下所示:
```java
import java.io.IOException;
import java.util.concurrent.*;
/**
* @className: DelayRecurse
* @Description:
* @Author: wangyifei
* @Date: 2025/3/21 9:38
*/
public class DelayRecurse {
public static void main(String[] args) throws IOException {
DO aDo = new DO(){
@Override
public Integer execute() {
return 1;
}
};
System.out.println(aDo.doTry(10));
// System.in.read();
}
public static abstract class DO<T , TT> {
public abstract T execute();
public T doTry(int cnt) {
return doTry(cnt , cnt);
}
public T doTry(int cnt , int sum) {
ScheduledFuture<T> schedule = null ;
if(cnt > 0){
ScheduledExecutorService pool = Executors.newScheduledThreadPool(3);
System.out.println("execute " + (sum - cnt + 1));
if(cnt == 1){
return execute();
}
schedule = pool.schedule(() -> this.doTry(cnt - 1 , sum), 2, TimeUnit.SECONDS);
}
try {
return schedule.get();
} catch (InterruptedException e) {
throw new RuntimeException(e);
} catch (ExecutionException e) {
throw new RuntimeException(e);
}
}
}
}
```