如何在一定时间后重试功能请求

时间:2009-10-22 02:52:20

标签: java

如果用户数据为空,如何重试发送尝试。最多2次重试,10次后重试1次?

public class UserHandler {
  private List users = new ArrayList();

  public void addUser(username) {} //adds user
  public Userdata findUser(username) {} //finds user

  public void sendTo(String username, String message) {
    Userdata user = findUser(username);
    if(user != null) {
        Out out = new Out(user.getClientSocket());
        out.println(message);
    } 
  }
}

我是否真的必须手动插入线程并将其睡在sendTo()?

编辑:服务器使用java 1.4.2

3 个答案:

答案 0 :(得分:4)

首先要解决的是更多的架构问题。在单线程程序中,序列通常是:

  1. 做东西;
  2. 致电sendTo();
  3. 做更多的事情。
  4. 你必须弄清楚你想要的是什么:

    1. 做东西;
    2. 致电sendTo();
    3. 如果(2)失败,请等待10秒再发送一次();
    4. 如果(3)失败,则抛出错误;
    5. 做更多的事情。
    6. 关键是这仍然是同步的。如果是这样,你需要一个线程。您应该使用Java 5 Executors。

      public void sendTo(final String username, final String message) {
        if (!internalSendTo(username, message)) {
          // attempt resend
          ExecutorService exec = Executors.newSingleThreadExecutor();
          final AtomicBoolean result = new AtomicBoolean(false);
          exec.submit(new Runnable() {
            boolean b = internalSendto(username, message);
            result.set(b);
          });
          try {
            exec.awaitTermination(10, TimeUnit.SECONDS);
          } catch (InterruptedException e) {
            // still didn't work
          } finally {
            exec.shutdownNow();
          }
        }
      }
      
      private boolean internalSendTo(String username, String message) {
        Userdata user = findUser(username);
        boolean success = false;
        if (user != null) {
          Out out = new Out(user.getClientSocket());
          // do the communication here
          success = true;
        }
        return success;
      }
      

      现在,这只是它如何运作的粗略草图。不过,它应该让你对这些问题有所了解。

      你想要这个或者你想要吗:

      1. 做东西;
      2. 致电sendTo();
      3. 如果(2)失败,请对发送进行排队并继续;
      4. 做更多的事情。
      5. 基本上这是异步方法。如果你这样走,你就必须回答如下问题:

        • 如果在10秒以上(或某个任意间隔)之后仍然无效,会发生什么?
        • 什么进程尝试sendTo()调用?
        • 如果他们阻止/死亡怎么办?
        • 我需要多个发件人吗?

        基本上它变得复杂得多。

答案 1 :(得分:3)

您的确切方案,使用Failsafe

RetryPolicy retryPolicy = new RetryPolicy()
  .retryWhen(null)
  .withMaxRetries(2)
  .withDelay(10, TimeUnit.SECONDS);

Userdata user = Failsafe.with(retryPolicy).get(() -> findUser(username));

它没有变得更简单。告诉你的朋友:)

答案 2 :(得分:0)

我建议使用AOP和Java注释。尝试jcabi-aspects的阅读机制:

@RetryOnFailure(attempts = 3)
public void sendTo(String username, String message) {
  // try to do it
}