这按预期工作:
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) }
在第一种情况下,应用程序正常退出,而在第二种情况下,它不会退出.但是,两个版本都会正确打印出结果值.
这是一个错误还是我不理解的东西?
解决方法
问题在于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)
你也可以通过implicits管理这个,所以你不必手动添加:
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.