这可以按预期工作:
object Planexecutor extends App {
import scalaz.concurrent.Future
import scala.concurrent.duration._
val f = Future.apply(longComputation)
val result = f.run
println(result)
}
这不是:
object Planexecutor extends App {
import scalaz.concurrent.Future
import scala.concurrent.duration._
val f = Future.apply(longComputation).timed(1.second)
val result = f.run
println(result)
}
在第一种情况下,应用程序正常退出,而在第二种情况下,它不会退出。但是,两个版本都会正确打印出结果值。
这是一个错误还是我不理解的东西?
答案 0 :(得分:5)
问题在于timed
正在使用的线程池。如果您查看source,您可以看到它使用的默认值为Strategy.DefaultTimeoutScheduler
,它只是一个通用的Java线程池,并且它的线程未设置为守护程序状态。 Future.apply
的默认线程池在其线程集上确实具有守护程序状态,因此JVM将正常关闭。要解决此问题,您可以在代码完成后手动关闭线程池:
scalaz.concurrent.Strategy.DefaultTimeoutScheduler.shutdown()
或者您可以传递不同的线程池:
val newTimeOutScheduler = Executors.newScheduledThreadPool(1, new ThreadFactory {
val defaultThreadFactory = Executors.defaultThreadFactory()
def newThread(r: Runnable) = {
val t = defaultThreadFactory.newThread(r)
t.setDaemon(true)
t
}
})
val f = Future.apply(longComputation).timed(1.second)(newTimeOutScheduler)
您也可以通过隐含进行管理,因此您无需手动添加此内容:
implicit val newTimeOutScheduler = Executors.newScheduledThreadPool(1, new ThreadFactory {
val defaultThreadFactory = Executors.defaultThreadFactory()
def newThread(r: Runnable) = {
val t = defaultThreadFactory.newThread(r)
t.setDaemon(true)
t
}
})
val f = Future.apply(longComputation).timed(1.second)
<强>更新强> 这是一个非常简单的修复,所以我做了pull request.