如何在 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 次,但这可能是基于计数或时间的。任何对您的用例有意义的东西。
我正在尝试每隔 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 次,但这可能是基于计数或时间的。任何对您的用例有意义的东西。