There are many cases in which you may wish to retry an operation a certain number of times. Examples are database failures, network communication failures or file IO problems.

Approach 1
This is the traditional approach and involves a counter and a loop.

final int numberOfRetries = 5 ;
final long timeToWait = 1000 ;
 
for (int i=0; i<numberOfRetries; i++) {
 //perform the operation
 try {
  Naming.lookup("rmi://localhost:2106/MyApp");
  break;
 }
 catch (Exception e) {
  logger.error("Retrying...",e);
  try {
   Thread.sleep(timeToWait);
  }
  catch (InterruptedException i) {
  }
 }
}

Approach 2
In this approach, we hide the retry counter in a separate class called RetryStrategy and call it like this:

public class RetryStrategy
{
 public static final int DEFAULT_NUMBER_OF_RETRIES = 5;
 public static final long DEFAULT_WAIT_TIME = 1000;
 
 private int numberOfRetries; //total number of tries
 private int numberOfTriesLeft; //number left
 private long timeToWait; //wait interval
 
 public RetryStrategy()
 {
  this(DEFAULT_NUMBER_OF_RETRIES, DEFAULT_WAIT_TIME);
 }
 
 public RetryStrategy(int numberOfRetries, long timeToWait)
 {
  this.numberOfRetries = numberOfRetries;
  numberOfTriesLeft = numberOfRetries;
  this.timeToWait = timeToWait;
 }
 
 /**
  * @return true if there are tries left
  */
 public boolean shouldRetry()
 {
  return numberOfTriesLeft > 0;
 }
 
 /**
  * This method should be called if a try fails.
  *
  * @throws RetryException if there are no more tries left
  */
 public void errorOccured() throws RetryException
 {
  numberOfTriesLeft --;
  if (!shouldRetry())
  {
   throw new RetryException(numberOfRetries +
     " attempts to retry failed at " + getTimeToWait() +
     "ms interval");
  }
  waitUntilNextTry();
 }
 
 /**
  * @return time period between retries
  */
 public long getTimeToWait()
 {
  return timeToWait ;
 }
 
 /**
  * Sleeps for the duration of the defined interval
  */
 private void waitUntilNextTry()
 {
  try
  {
   Thread.sleep(getTimeToWait());
  }
  catch (InterruptedException ignored) {}
 }
 
 public static void main(String[] args) {
  RetryStrategy retry = new RetryStrategy();
  while (retry.shouldRetry()) {
   try {
    Naming.lookup("rmi://localhost:2106/MyApp");
    break;
   }
   catch (Exception e) {
    try {
     retry.errorOccured();
    }
    catch (RetryException e1) {
     e.printStackTrace();
    }
   }
  }
 }
}

Approach 3
Approach 2, although cleaner, hasn't really reduced the number of lines of code we have to write. In the next approach, we hide the retry loop and all logic in a separate class called RetriableTask. We make the operation that we are going to retry Callable and wrap it in a RetriableTask which then handles all the retrying for us, behind-the-scenes:

public class RetriableTask<T> implements Callable<T> {
 
 private Callable<T> task;
 public static final int DEFAULT_NUMBER_OF_RETRIES = 5;
 public static final long DEFAULT_WAIT_TIME = 1000;
 
 private int numberOfRetries; // total number of tries
 private int numberOfTriesLeft; // number left
 private long timeToWait; // wait interval
 
 public RetriableTask(Callable<T> task) {
  this(DEFAULT_NUMBER_OF_RETRIES, DEFAULT_WAIT_TIME, task);
 }
 
 public RetriableTask(int numberOfRetries, long timeToWait,
                      Callable<T> task) {
  this.numberOfRetries = numberOfRetries;
  numberOfTriesLeft = numberOfRetries;
  this.timeToWait = timeToWait;
  this.task = task;
 }
 
 public T call() throws Exception {
  while (true) {
   try {
    return task.call();
   }
   catch (InterruptedException e) {
    throw e;
   }
   catch (CancellationException e) {
    throw e;
   }
   catch (Exception e) {
    numberOfTriesLeft--;
    if (numberOfTriesLeft == 0) {
     throw new RetryException(numberOfRetries +
     " attempts to retry failed at " + timeToWait +
     "ms interval", e);
    }
    Thread.sleep(timeToWait);
   }
  }
 }
 
 public static void main(String[] args) {
  Callable<Remote> task = new Callable<Remote>() {
   public Remote call() throws Exception {
    String url="rmi://localhost:2106/MyApp";
    return (Remote) Naming.lookup(url);
   }
  };
 
  RetriableTask<Remote> r = new RetriableTask<Remote>(task);
  try {
   r.call();
  }
  catch (Exception e) {
   e.printStackTrace();
  }
 }
}

Also see:

References:

Java Retry implement的更多相关文章

  1. java retry:详解

    发现 今天在探秘线程池原理知识点,在阅读JDK源码时遇到程序代码中出现如下代码,因为之前没有遇到过,于是特地记录下来并谷歌了一番,后面我自己做了一些简要的验证和分析. 验证 网上溜达一番发现,这ret ...

  2. Effective Java 74 Implement Serializable judiciously

    Disadvantage of Serializable A major cost of implementing Serializable is that it decreases the flex ...

  3. Effective Java Index

    Hi guys, I am happy to tell you that I am moving to the open source world. And Java is the 1st langu ...

  4. Java Algorithm Problems

    Java Algorithm Problems 程序员的一天 从开始这个Github已经有将近两年时间, 很高兴这个repo可以帮到有需要的人. 我一直认为, 知识本身是无价的, 因此每逢闲暇, 我就 ...

  5. 为什么Java中的String是设计成不可变的?(Why String is immutable in java)

    There are many reasons due to the string class has been made immutable in Java. These reasons in vie ...

  6. 更好的 java 重试框架 sisyphus 入门简介

    What is Sisyphus sisyphus 综合了 spring-retry 和 gauva-retrying 的优势,使用起来也非常灵活. 为什么选择这个名字 我觉得重试做的事情和西西弗斯很 ...

  7. Jmeter3.0新特性

    2016-5-19昨日,Jmeter又更新了新版本. 那么新版本有哪些新特性呢? Changes   This page details the changes made in the current ...

  8. jackson官方快速入门文档

    官方地址: http://jackson.codehaus.org/ http://wiki.fasterxml.com/JacksonInFiveMinutes http://wiki.faster ...

  9. Maven聚合与继承的实例讲解(二)

    继续上一节讲Maven的内容,我们这个节继续讲Maven继承和聚合的其他内容.    现在我们新建一个实例来测试Maven有关于聚合的部分     测试开始 一.建立以pom为packaging的项目 ...

随机推荐

  1. BZOJ4476 JSOI2015送礼物(分数规划+单调队列)

    看到这个式子当然先二分答案.得max-min-(j-i+k)ans>=0. 显然max-min相同的情况下所选区间长度越短越好,所以max和min都应该取在边界.那么实际上我们根本不用管端点是否 ...

  2. [洛谷P2602][ZJOI2010]数字计数

    题目大意:求区间$[l,r]$中数字$0\sim9$出现个数 题解:数位$DP$ 卡点:无 C++ Code: #include <cstdio> #include <iostrea ...

  3. NAS星云链 入门之从零开发第一个DAPP

    应该有很多小伙伴和我一样,一直想去入手学习区块链,但是总无从下手,有些概念感觉理解了,有感觉没理解.其实这都是“没实践”的锅. 所谓看十遍不如想一遍,想一遍不如做一遍.这不最近星云链nebulas正有 ...

  4. cookie 是存储于访问者的计算机中的变量

    今天把javascript如何用来创建及存储cookie复习了一下,其中的一点体会拿出来和大家讨论,首先看一下基础知识: 什么是cookie cookie 是存储于访问者的计算机中的变量.每当同一台计 ...

  5. 常见编程语言对REPL支持情况小结

    最近跟一个朋友聊起编程语言的一些特性,他有个言论让我略有所思:“不能REPL的都是渣”.当然这个观点有点偏激,但我们可以探究一下,我们常用的编程语言里面,哪些支持REPL,哪些不支持,还有REPL的一 ...

  6. Maven如何打包本地依赖包

    有的jar包,在maven中心库里面是没有的,那么,如何在项目中使用呢? 假设我们需要使用:apache-ant-zip-2.3.jar 将该jar包,放在项目的lib目录,例如: 在pom.xml里 ...

  7. 带依赖包的maven打包配置

    转载自:http://outofmemory.cn/code-snippet/2594/carry-yilai-bao-maven-dabao-configuration 可以在maven的packa ...

  8. maven在add dependecy时搜索不出jar包的解决办法

    一:前言 其实我一直都很头疼maven的项目管理的,因为觉得用起来还是没有那么方便的啊,不过今天我自己算是小弄了下maven项目的故那里,是一个同事在配置maven的项目,我去凑了下热闹而已,现在自己 ...

  9. 随机洗牌算法Knuth Shuffle和错排公式

    Knuth随机洗牌算法:譬如现在有54张牌,如何洗牌才能保证随机性.可以这么考虑,从最末尾一张牌开始洗,对于每一张牌,编号在该牌前面的牌中任意一张选一张和当前牌进行交换,直至洗到第一张牌为止.参考代码 ...

  10. 优化IDEA启动速度,快了好多。后面有什么优化点,会继续往里面添加

    1.优化启动 修改bin/idea.exe.vmoptions文件如下: -Xms256m   初始堆大小-Xmx384m   最大堆大小 -XX:+UseParNewGC   使用并行收集算法 2. ...