asynchronous - 如何在groovy中从TimerTask返回值
问题描述
我试图每3 秒调用一次getStatus方法并检查我是否从我的数据库中获得了完成状态(为此测试目的删除数据库代码)。一旦我得到状态“完成”,我就会退出 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)
}
解决方案
问题是您正在调度计时器任务,然后立即从 getStatus() 返回响应的当前值。大约 3 秒后,该任务将局部变量设置为“完成”,但任务之外的任何人现在都没有看到它。
更好的方法可能是让 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 次,但这可能是基于计数或时间的。任何对您的用例有意义的东西。
推荐阅读
- eclipse - Eclipse - Kotlin
- css - 变形 svg 对象
- python - sqlalchemy - 通过返回 SQL 服务器权限错误的确切 pyodbc 字符串?
- css - 在 Css 中对齐水平规则,未正确对齐
- javascript - React:target.dataset.key 有时会返回 undefined
- python - 如何在 MongoDB 的数组中查找具有最大值和最小值的文档
- java - 在Java中,如何指定泛型类型?
- github - 如何让我的 Git 提交显示在 github 上?
- html - 如何将两个表单内联在一起
- java - 使用 LittleProxy 拦截、操作和转发请求