我是groovy的新手,有以下简单代码段:
import java.util.concurrent.CountDownLatch
import java.util.concurrent.TimeUnit
CountDownLatch called = new CountDownLatch(1)
Timer timer = new Timer()
timer.schedule(new TimerTask() {
void run() {
called.countDown()
}
}, 0)
assert called.await(2, TimeUnit.SECONDS)
在命令行上运行时,它只是挂在那里,什么也没有发生。我希望该程序应立即退出。那我哪里做错了?
答案 0 :(得分:2)
实际上,不是await
导致您的案件被吊销。只是Timer
的线程不是守护程序。直到所有其余正在运行的线程都是守护程序,JVM才能终止。正如Thread#setDaemon()
javadoc所说:
...当仅运行的所有线程都是守护程序线程时,Java虚拟机退出。
所以就您而言
CountDownLatch called = new CountDownLatch(1)
Timer timer = new Timer(true) //true means the underlying thread is a daemon
timer.schedule(new TimerTask() {
void run() {
called.countDown()
}
}, 0)
assert called.await(2, TimeUnit.SECONDS)
println("It's not await that leads to hanging")
CountDownLatch called = new CountDownLatch(1)
Timer timer = new Timer() //now the underlying thread is NOT a daemon
timer.schedule(new TimerTask() {
void run() {
called.countDown()
}
}, 0)
assert called.await(2, TimeUnit.SECONDS)
println("It's not await that leads to hanging")
timer.cancel()//now we are done. All scheduled tasks will be cancelled. However, the running one will finish its job
P.S。如果您想要更灵活的计划方式,可以看看ScheduledThreadPoolExecutor。正如Timer
的javadoc所说:
...实际上,它是Timer / TimerTask组合的更通用的替代品,因为它允许多个服务线程,接受各种时间单位,并且不需要子类化TimerTask(只需实现Runnable)。使用一个线程配置ScheduledThreadPoolExecutor使其等同于Timer。