使用 GPars 分派异步任务并立即 return
Use GPars to dispatch an async task and return immediately
我想要一个分派异步任务的方法,returns 立即。我不需要等待结果。
我想要这样的东西工作:
/**
* runs a job and return job id for later montoring.
*/
def int runJob(){
int jobId = createJob() // returns immediately
task{
doSomthingThatTakesSomeTime()
}.then {stepResult-> doSmtgElse(stepResult)}
return jobId
}
在上述情况下,任务不会 运行,因为没有调用 .get()
,但是,如果我执行 .get() ,该方法将不会 return jobId 直到任务完成。
我怎样才能分派任务并且仍然return立即?
您可以 运行 此示例作为 Groovy 脚本:
@Grapes(
@Grab(group='org.codehaus.gpars', module='gpars', version='1.2.1')
)
import java.util.concurrent.*
import groovyx.gpars.*
def doSomethingThatTakesSomeTime(){
println "calculating..."
for(long i: 0..100){
Thread.sleep(i)
}
println "*done*"
"Done with doSomethingThatTakesSomeTime"
}
def doSomethingElse(){
for(int x:0..1000) print "."
println "doSomethingElse done."
}
/**
* runs a job and return job id for later montoring.
*/
def runJob(){
GParsPool.withPool(){
Future future = createJob() // returns immediately
doSomethingElse() //Do someting else while the async process is running
//Ok, thats done, but the longer runningprocess is still running, return the future
future
}
}
Future createJob(){
//create a new closure, which starts the original closure on a thread pool
Closure asyncFunction = { doSomethingThatTakesSomeTime() }.async()
//Invoke the function, return a Future
asyncFunction()
}
def job = runJob()
//println "\n\nResult is: " + job.get()
如果您 运行 脚本 "as-is",您将看到它 运行s 并且长 运行ning 作业会打印 *done*
指示它实际上 运行 完成了,即使底部调用 Future.get()
的行被注释掉并且从未调用过。
如果您取消注释最后一行,您将看到调用 Future.get()
后打印的结果
阅读@pczeus 的回答和 Jérémie B 的评论后,我想到了这个:
import static groovyx.gpars.dataflow.Dataflow.task
def int longTask(){
def counter = 0
10.times {
println "longTask_${counter}"
counter++
sleep 10
}
counter
}
def int getSomeString() {
def jobId=55
task {
longTask()
}.then { num -> println "completed running ${num} times" }
return jobId
}
println getSomeString()
sleep 2000
这会打印:
longTask_0
55
longTask_1
longTask_2
longTask_3
longTask_4
longTask_5
longTask_6
longTask_7
longTask_8
longTask_9
completed running 10 times
这就是我的意图:
longTask() 在后台 运行,getSomeString() 不等待长任务就重新运行,只要程序仍然是 运行(因此睡眠 2000),即使是子句'then' 部分被执行
我想要一个分派异步任务的方法,returns 立即。我不需要等待结果。 我想要这样的东西工作:
/**
* runs a job and return job id for later montoring.
*/
def int runJob(){
int jobId = createJob() // returns immediately
task{
doSomthingThatTakesSomeTime()
}.then {stepResult-> doSmtgElse(stepResult)}
return jobId
}
在上述情况下,任务不会 运行,因为没有调用 .get() ,但是,如果我执行 .get() ,该方法将不会 return jobId 直到任务完成。
我怎样才能分派任务并且仍然return立即?
您可以 运行 此示例作为 Groovy 脚本:
@Grapes(
@Grab(group='org.codehaus.gpars', module='gpars', version='1.2.1')
)
import java.util.concurrent.*
import groovyx.gpars.*
def doSomethingThatTakesSomeTime(){
println "calculating..."
for(long i: 0..100){
Thread.sleep(i)
}
println "*done*"
"Done with doSomethingThatTakesSomeTime"
}
def doSomethingElse(){
for(int x:0..1000) print "."
println "doSomethingElse done."
}
/**
* runs a job and return job id for later montoring.
*/
def runJob(){
GParsPool.withPool(){
Future future = createJob() // returns immediately
doSomethingElse() //Do someting else while the async process is running
//Ok, thats done, but the longer runningprocess is still running, return the future
future
}
}
Future createJob(){
//create a new closure, which starts the original closure on a thread pool
Closure asyncFunction = { doSomethingThatTakesSomeTime() }.async()
//Invoke the function, return a Future
asyncFunction()
}
def job = runJob()
//println "\n\nResult is: " + job.get()
如果您 运行 脚本 "as-is",您将看到它 运行s 并且长 运行ning 作业会打印 *done*
指示它实际上 运行 完成了,即使底部调用 Future.get()
的行被注释掉并且从未调用过。
如果您取消注释最后一行,您将看到调用 Future.get()
阅读@pczeus 的回答和 Jérémie B 的评论后,我想到了这个:
import static groovyx.gpars.dataflow.Dataflow.task
def int longTask(){
def counter = 0
10.times {
println "longTask_${counter}"
counter++
sleep 10
}
counter
}
def int getSomeString() {
def jobId=55
task {
longTask()
}.then { num -> println "completed running ${num} times" }
return jobId
}
println getSomeString()
sleep 2000
这会打印:
longTask_0
55
longTask_1
longTask_2
longTask_3
longTask_4
longTask_5
longTask_6
longTask_7
longTask_8
longTask_9
completed running 10 times
这就是我的意图: longTask() 在后台 运行,getSomeString() 不等待长任务就重新运行,只要程序仍然是 运行(因此睡眠 2000),即使是子句'then' 部分被执行