驽马十驾 驽马十驾

驽马十驾,功在不舍

目录
共享一个Java9之后可以用的FutureUtils小工具
/  

共享一个Java9之后可以用的FutureUtils小工具

直接上代码,下面的代码包括了几个功能

  • 超时设置
  • 异常内部打印
  • 异常情况(超时异常和其他异常)时直接返回默认值

这样带来的好处时,避免任务调度不过来的时候,卡在队列中,无限等待。

object FutureUtils {

    private val log: Logger = LoggerFactory.getLogger(FutureUtils::class.java)

    /**
     * 执行带超时的异步任务,如果执行失败或者遇到异常,都会返回默认值
     * @param defaultValue U 发生异常或者超时时的默认值
     * @param timeout 超时值
     * @param unit 超时单位
     * @param taskName 任务名称
     * @param executor 线程池
     * @param supplier Function0<U>
     */
    @JvmStatic
    fun <U> supplyAsync(
        defaultValue: U,
        timeout: Long,
        unit: TimeUnit,
        taskName:String,
        executor: Executor,
        supplier: () -> U
    ): CompletableFuture<U> {
        return CompletableFuture.supplyAsync(supplier, executor)
            .orTimeout(timeout, unit)
            .handle { res, ex ->
                if (ex == null)
                    return@handle res
                else {
                    if (ex is TimeoutException) {
                        log.error("【CompletableFuture】任务$taskName 超过指定时间:$timeout,返回默认值:$defaultValue")
                    } else {
                        log.error("【CompletableFuture】任务$taskName 发生异常,返回默认值:$defaultValue,异常堆栈如下所示", ex)
                    }
                    return@handle defaultValue
                }
            }
    }
}

备注几点

  • supplier 放在最后是因为kotlin支持最后一个参数是函数的时候,写法更简单
  • 其中orTimeout时Java9之后才可以用的,是不是多了一个升级到JDK11的理由?
积土成山,风雨兴焉。积水成渊,蛟龙生焉。