用JDK8的函数式接口实现简单的重试机制

重试机制的使用场景

在任何系统中,任何组件都有一定的概率出错,在代码中就不得不考虑应对这些出错场景,提高代码的健壮性和业务的稳定性。而重试就是一种非常普通的容错机制,在出现问题的时候,以一定的频率、一定的次数重试几次,可提高系统的容错能力。

本文就用JDK8的函数式接口来实现一个非常简单的重试框架。

代码实现

  • MyRetry.java:
package com.function.functionalinterface;

import java.util.concurrent.TimeUnit;

/**
 * 重试函数式接口
 *
 */
@FunctionalInterface
public interface MyRetry {
    /**
     * 执行某种操作的函数结构定义,没有入参,返回值为布尔类型
     * @return
     */
    boolean action();

    /**
     * 最大重试次数5次
     */
    public static final int MAX_RETRY_COUNT_5 = 5;

    /**
     * 重试间隔时间3秒
     */
    public static final int INTERVAL_SECONDS_3 = 3;

    /**
     * 实现重试
     * 
     * @param maxRetryCount
     *            最大重试次数
     * @param workFunction
     *            每次重试所执行的工作函数
     * @param intervalFunctin
     *            重试间隔期间执行的函数,比如sleep一段时间
     */
    public static void retry(int maxRetryCount, MyRetry workFunction,
            MyRetry intervalFunctin) {
        // 如果最大重试次数小于1,或重试工作函数为空,直接返回
        if (maxRetryCount < 1 || null == workFunction) {
            return;
        }

        // 执行最大重试次数次重试操作
        for (int i = 0; i < maxRetryCount; i++) {
            // 如果本次的执行结果为成功,则不再继续重试
            if (workFunction.action()) {
                return;
            }

            // 如果本次的执行结果为失败,则执行重试间隔函数之后继续重试执行工作函数
            intervalFunctin.action();
        }

        System.out.println("have tried maxRetryCount!");
    }

    /**
     * 让当前线程睡眠指定秒数
     * 
     * @param seconds
     * @return
     */
    public static boolean doSleep(int seconds) {
        try {
            TimeUnit.SECONDS.sleep(seconds);
            return true;
        } catch (InterruptedException e) {
            System.out.println("exception occurs when doSleep, e = " + e);
            return false;
        }
    }
}

  • MyRetryTest.java:
package com.function.functionalinterface;

/**
 * 测试重试函数式接口
 *
 */
public class MyRetryTest {

    public static void main(String[] args) {
        // 工作函数入参
        boolean param = true;
        MyRetry.retry(MyRetry.MAX_RETRY_COUNT_5, () -> doWork(param),
                () -> MyRetry.doSleep(MyRetry.INTERVAL_SECONDS_3));
    }

    /**
     * 工作函数
     * 
     * @param param
     *            一个布尔类型的入参
     * @return
     */
    public static boolean doWork(boolean param) {
        System.out.println("start to do some work...");

        // 为简单期间,将入参param的值取反,模拟工作函数的执行结果
        boolean result = !param;
        if (result) {
            System.out.println("doWork success!");
        } else {
            System.out.println("doWork failed!");
        }

        return result;
    }

}

  • 运行MyRetryTest.java,输出结果如下:
start to do some work...
doWork failed!
start to do some work...
doWork failed!
start to do some work...
doWork failed!
start to do some work...
doWork failed!
start to do some work...
doWork failed!
have tried maxRetryCount!

可见上述代码每隔3秒重试一次,一共重试了5次。


本文代码:我的GitHub

©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 关于Mongodb的全面总结 MongoDB的内部构造《MongoDB The Definitive Guide》...
    中v中阅读 32,403评论 2 89
  • 传送门 解读阿里Java开发手册(v1.1.1) - 异常日志 前言 阿里Java开发手册谈不上圣经,但确实是大量...
    kelgon阅读 4,519评论 4 50
  • 概念:微服务就是一些可独立运行、可协同工作的小的服务。微服务是现在特别流行的服务,微服务的字面意思是大家都很好理解...
    程序员技术圈阅读 3,500评论 2 47
  • 前言 本开发规范基于《阿里巴巴Java开发手册终极版》修改,并集成我们自己的项目开发规范,整合而成。 为表示对阿里...
    4ea0af17fd67阅读 5,779评论 0 5
  • 人世间的快乐大抵相同 不同层次的人各有各的痛苦 如果对于一个人 心中存有爱 出于共情的需要 一定会与之共享快乐和痛...
    胡涂格格阅读 709评论 0 0

友情链接更多精彩内容