如何在 groovy 中从 TimerTask 获取 return 值

How to return value from TimerTask in groovy

我正在尝试每隔 3 秒 调用 getStatus 方法并检查我是否得到 Done 我的数据库中的状态(出于此测试目的删除数据库代码)。一旦我得到状态“Done”,我就从 while 循环中出来,我想 return 这个状态到 testMethod。但是我的代码没有 return 将任何东西返回给 CompletableFuture。我在这里做错了什么 - 有人可以帮我解决这个问题吗?我的代码片段:

CompletableFuture.supplyAsync({ -> getStatus()
        }).thenAccept({ status -> testMethod(status) })

def getStatus() {
        def response
        Timer timer = new Timer()
        TimerTask timerTask = new TimerTask(){
                    @Override
                    public void run() {
                        while(true) {
                            // Doing some DB operation to check the work status is changing to Done and assigning to response
                            response = "Done"
                            if (response == "Done") {
                                timer.cancel()
                                break;
                            }

                        }
                    }
                }
        timer.schedule(timerTask, 3000)
        return response
    }


def testMethod(status) {
        System.out.println("testMethod... " +status)
    }

问题是您正在安排计时器任务,然后立即 return 来自 getStatus() 的当前响应值。大约 3 秒后,该任务将局部变量设置为 "Done",但现在任务外没有人在看它。

更好的方法可能是让 getStatus 本身 return CompletableFuture。任务完成后可以填充哪个任务。

所以像这样:

getStatus().thenAccept({ status -> testMethod(status) })

def getStatus() {
   def future = new CompletableFuture<String>()
   Timer timer = new Timer()
   TimerTask timerTask = new TimerTask(){
      @Override
      public void run() {
         while(true) {
            // Doing some DB operation to check the work status is changing to Done and assigning to response
            def response = "Done"
            if (response == "Done") {
               timer.cancel()
               future.complete(response)
               break;
            }

         }
      }
   }
   timer.schedule(timerTask, 3000)
   return future
}


def testMethod(status) {
   System.out.println("testMethod... " +status)
}

编辑 - 要添加某种超时,您可以改为使用 ScheduledExecutorService,如下所示:

import java.util.concurrent.*


ScheduledExecutorService executor = Executors.newScheduledThreadPool(2)

getStatus(executor).thenAccept({ status -> testMethod(status) })


def getStatus(executor) {
   def future = new CompletableFuture<String>()

   def count = 0

   def task

   def exec = {
      println("Running : $count")
      // Doing some DB operation to check the work status is changing to Done and assigning to response
      def response = "NotDone"
      if (response == "Done") {
         future.complete(response)
         task.cancel()
      }
      else if (++count == 10) {
         future.complete("Failed")
         task.cancel()
      }
   } as Runnable

   task = executor.scheduleAtFixedRate(exec, 3, 3, TimeUnit.SECONDS)

   future
}


def testMethod(status) {
   System.out.println("testMethod... " +status)
}

所以我只是使用迭代计数将其停止 运行 超过 10 次,但这可能是基于计数或时间的。任何对您的用例有意义的东西。