【问题标题】:How to sleep before retrying in struts action?在重试struts动作之前如何睡觉?
【发布时间】:2019-05-23 15:41:12
【问题描述】:

我有一个用例,我的 struts 操作从文件系统读取文件,然后在服务器响应中返回它。我想添加重试逻辑,让我的请求在重试读取文件之前休眠一段时间,实现这一目标的最佳方法是什么?

我想在每次重试之间等待 1 秒后重试 10 次。我发现 Thread.sleep(1000) 使当前线程进入睡眠状态。这是正确的方法吗?


public String execute()
{
    for(int i = 0; i < 10; i++) {
        // Read the file system
        if (break_condition) {
            break;
        }
        Thread.sleep(1000);
    }
}

有没有更好的方法来实现这一点?

【问题讨论】:

    标签: java struts2


    【解决方案1】:

    最好不要在服务器上下文中使用Thread.sleep,因为它可能会产生不必要的影响。

    根据可用的服务器和框架,建议的方法会有所不同。然而,这个想法的核心是您使用特定的 API 进行调度,或者在将来执行(重试)服务器提供的某些操作,并避免使用 Thread.sleep()

    主要区别在于线程在继续之前不会休眠并保持空闲状态。线程会在特定时间后通知服务器做某事,然后线程会继续工作。

    如果您在 Java-EE 环境中使用 TimerService 将是一个好主意。它可以使用 TimerService.createSingleActionTimer() 来实现。

    例如,如果您在 Jave EE 服务器中,您可以执行以下操作:

    import javax.annotation.Resource;
    import javax.ejb.SessionContext;
    import javax.ejb.Timer;
    import javax.ejb.Stateless;
    import javax.ejb.Timeout;
    import javax.ejb.TimerConfig;
    
    @Stateless
    public class RetryWithWaitBean {
    
    
       @Resource
       private SessionContext context;
    
        /**
        *Create a timer that will be activated after the duration passes.
        */
       public void doActionAfterDuration(long durationMillis) {
          final TimerConfig timerConfig= new TimerConfig()
          timerConfig.setPersistent(false);
          context.getTimerService()..createSingleActionTimer(durationMillis,timerConfig);
       }
    
       /** Automatically executed by server on timer expiration.
       */
       @Timeout
       public void timeout(Timer timer) {
          System.out.println("Trying after timeout. Timer: " + timer.getInfo()); 
          //Do custom action 
          doAction();
    
          timer.cancel();
       }
    
       /**
        * Doing the required action 
        */
       private void doAction(){
          //add your logic here. This code will run after your timer.
        System.out.println("Action DONE!"); 
      }
    }
    

    然后你可以这样使用它:

     //This code should be in a managed context so that the server injects it.
     @EJB 
     private RetryWithWaitBean retryWithWaitBean ;
    

    那么你就可以这样使用了。

    //do an action after 3000 milliseconds
    retryWithWaitBean.doActionAfterDuration(3000);
    

    根据您使用的框架,有很多方法可以实现类似的结果。

    【讨论】:

    • 你用一些代码编辑你的例子,这样我就可以理解这如何解决我的用例?我想阻止我的服务器请求,直到所有重试都完成
    猜你喜欢
    • 2013-04-29
    • 2012-11-03
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-06
    • 2021-10-11
    • 1970-01-01
    相关资源
    最近更新 更多