You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在Kotlin中通过参数配置超时与最大重试时长实现重试?

实现支持动态参数的重试功能

原有的注解式重试(如@Retry(retryInterval = 60))依赖编译期确定的常量值,无法满足调用者动态传入最大重试时长和重试间隔的需求。这里推荐用高阶函数封装重试逻辑,这是Kotlin中实现此类动态控制逻辑的常规方案,既保证复用性,又能灵活接收调用者参数。

基础实现(阻塞式)

封装一个通用的重试函数,接收重试参数和目标执行逻辑:

fun <T> retryWithDynamicParams(
    maxRetryDurationMs: Long,
    retryIntervalMs: Long,
    block: () -> T
): T {
    val startTime = System.currentTimeMillis()
    var lastException: Exception? = null

    while (System.currentTimeMillis() - startTime < maxRetryDurationMs) {
        try {
            // 执行目标逻辑,成功则直接返回结果
            return block()
        } catch (e: Exception) {
            lastException = e
            // 等待重试间隔后继续循环
            Thread.sleep(retryIntervalMs)
        }
    }

    // 超时后抛出最后一次异常,或自定义异常
    throw lastException ?: RuntimeException("重试超时,未执行成功")
}

调用示例

// 调用时传入动态参数:最大重试3秒,每次间隔500毫秒
val result = retryWithDynamicParams(3000, 500) {
    doSomething(args)
}

进阶优化

1. 自定义重试异常范围

默认会捕获所有异常并重试,可添加参数控制仅对特定异常重试:

fun <T> retryWithDynamicParams(
    maxRetryDurationMs: Long,
    retryIntervalMs: Long,
    retryOn: (Exception) -> Boolean = { true }, // 默认所有异常都重试
    block: () -> T
): T {
    val startTime = System.currentTimeMillis()
    var lastException: Exception? = null

    while (System.currentTimeMillis() - startTime < maxRetryDurationMs) {
        try {
            return block()
        } catch (e: Exception) {
            if (retryOn(e)) {
                lastException = e
                Thread.sleep(retryIntervalMs)
            } else {
                // 不满足重试条件,直接抛出异常
                throw e
            }
        }
    }

    throw lastException ?: RuntimeException("重试超时,未执行成功")
}

// 调用示例:仅对IO异常重试
val result = retryWithDynamicParams(3000, 500, { it is IOException }) {
    doSomething(args)
}

2. 协程版本(非阻塞)

如果项目用Kotlin协程,可替换Thread.sleep为delay,避免阻塞线程:

import kotlinx.coroutines.delay
import kotlinx.coroutines.coroutineScope

suspend fun <T> retryWithDynamicParamsCoroutine(
    maxRetryDurationMs: Long,
    retryIntervalMs: Long,
    retryOn: (Exception) -> Boolean = { true },
    block: suspend () -> T
): T = coroutineScope {
    val startTime = System.currentTimeMillis()
    var lastException: Exception? = null

    while (System.currentTimeMillis() - startTime < maxRetryDurationMs) {
        try {
            return@coroutineScope block()
        } catch (e: Exception) {
            if (retryOn(e)) {
                lastException = e
                delay(retryIntervalMs)
            } else {
                throw e
            }
        }
    }

    throw lastException ?: RuntimeException("重试超时,未执行成功")
}

这种高阶函数的方式比零散写while循环更易维护,也能在多个地方复用重试逻辑,是业内处理动态重试需求的常规做法。

内容的提问来源于stack exchange,提问作者Kevin2566

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.15 08:52:04