如何从Groovy中的TimerTask返回值

时间:2018-08-01 14:12:43

标签: asynchronous groovy timer timertask completable-future

我试图每 3秒调用一次 getStatus 方法,并检查是否从数据库中获取了 Done 状态(删除数据库)测试代码)。一旦获得状态“ 完成”,我就退出了while循环,我想将此状态返回给testMethod。但是我的代码没有将任何东西返回给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)
    }

1 个答案:

答案 0 :(得分:0)

问题是您正在计划计时器任务,然后立即从getStatus()返回响应的当前值。大约3秒钟后,任务将局部变量设置为“ Done”,但任务外没有人正在查看该变量。

更好的方法可能是让getStatus本身返回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次,但这可能是基于计数或时间的。无论哪种情况都适合您的用例。