加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 综合聚焦 > 服务器 > 安全 > 正文

如何在使用Scalaz Futures和定时功能时正确退出程序

发布时间:2020-12-16 18:07:57 所属栏目:安全 来源:网络整理
导读:这按预期工作: 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
这按预期工作:

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.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读