【问题标题】:Java while loop with certain timeJava while循环有一定的时间
【发布时间】:2019-03-21 02:41:31
【问题描述】:

我使用消费者从队列中获取项目并将这些项目发送到外部 API

public void run(){
    try {
        while(true){
             //will peek() an item from a queue and send it to an external API
             sendRequest(item);
             thread.sleep(100);
        }
    } catch(InterruptedException e){
        Thread.currentThread().interrupt();
    }
}

还有另一种发送请求的方法

public void sendRequest(JSONibject item){
     // send request

    if(response.getStatus() == 200){
        //will remove the item from the queue
    }
    if(response.getStatus() == 500){
        //keep the item in the queue and set time for resending
    }
}

所以我想做的是当我得到 500 响应时,这意味着服务器没有启动。我会将这些项目保留在队列中,并尝试每 5 分钟重新发送这些项目。在这种情况下如何控制 while 循环?

【问题讨论】:

    标签: java time while-loop timer


    【解决方案1】:

    sendRequest在成功时返回true,在失败时返回false
    然后在while循环中,创建第二个循环:

    while (!sendRequest(item)) {
        thread.sleep(1000*60*5);
    }
    

    或者sendRequest中的类似内容:

    if(response.getStatus() == 500){
        thread.sleep(1000*60*5);
        sendRequest(item);
    }
    

    【讨论】:

      【解决方案2】:

      不确定您的整个上下文,但请尝试以下操作。

      所以你需要做的是在消费者方法或<JSONibject> 类型的全局范围内有另一个ArrayArrayListList。在这个array/arraylist/list 中,只需添加那些返回code 500 的项目。使用 Timer 安排每 5 分钟运行一次,并从该 array/arraylist/list 发送所有项目。

      首先,通过导入创建一个计时器。 (同时导入 TimerTask)

      import java.util.Timer;
      import java.util.TimerTask;
      

      然后创建一个计时器对象和 ArrayList 并以如下方式实现逻辑。

       public void run() {
          try {
              ArrayList<JSONibject> itemsToResend = new ArrayList<>();
              Timer timer = new Timer();
              while (true) {
                  //will peek() an item from a queue and send it to an external API
                  JSONibject output = sendRequest(item);
                  if (output == null) {
                      itemsToResend.add(output);
                  }
      
                  //This will run evey 5 minutes.
                  timer.scheduleAtFixedRate(new TimerTask() {
                      @Override
                      public void run() {
                          if(itemsToResend.size() > 0){
                              //Apply a loop to send the items again,
                              //Remove those items that are returned null.
                          }
                      }
                  }, 5 * 60 * 1000, 5 * 60 * 1000);
      
                  Thread.sleep(100);
              }
      
          } catch (InterruptedException e) {
              Thread.currentThread().interrupt();
          }
      

      请在Timer 上查看此主题以了解更多信息

      您还需要将sendRequest 更改为:

      public JSONibject sendRequest(JSONibject item) {
          // send request
      
          if (response.getStatus() == 200) {
              //Means consumed
              return null;
          }
          if (response.getStatus() == 500) {
              //Means not consumed and we should retry after 5 min.
              return item;
          }
      }
      

      也许这会给你一些起点或方向。

      【讨论】:

        【解决方案3】:

        您也可以在此处使用自定义异常。 例如,创建自定义异常类为

        public class ServerDownException extends Exception {
              public ServerDownException(String error) {
                     super(error);
              }
        }
        

        ...

        public void run(){
        try {
            while(true){
               try {
                 //will peek() an item from a queue and send it to an external API
                 sendRequest(item);
                 thread.sleep(100);
               } catch(ServerDownException ex) {
                 thread.sleep(/*milliseconds*/ 5000);
               }
            }
        } catch(InterruptedException e){
            Thread.currentThread().interrupt();
        }
        }
        

        ....

        public void sendRequest(JSONibject item) throws ServerDownException {
         // send request
        
        if(response.getStatus() == 200){
            //will remove the item from the queue
        }
        if(response.getStatus() == 500){
            //keep the item in the queue and set time for resending
            throw new ServerDownException("500 Server Down Error");
        }
        

        }

        您可以使用多个自定义异常类来处理不同的服务器错误。

        【讨论】:

        • 提示:在这种情况下,“服务器启动”不是exceptional event,而是预期的情况。将异常重命名为 ServerDownException 会更容易混淆,因为在这种情况下会抛出异常。
        • 谢谢@LuCio。更新了我的答案。
        猜你喜欢
        • 2011-06-20
        • 2011-02-02
        • 2013-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-01-14
        • 1970-01-01
        • 2014-03-29
        相关资源
        最近更新 更多