Scala 关闭挂钩从不运行? [英] Scala shutdown hooks never running?

查看:60
本文介绍了Scala 关闭挂钩从不运行?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

sys.addShutdownHook 的 scaladoc 说不能保证关闭钩子.现在这是完全合理的,因为如果您向 JVM 发送 SIGKILL 或任何 Windows 等效项,JVM 几乎无法运行关闭挂钩.

The scaladoc for sys.addShutdownHook says shutdown hooks are NOT guaranteed to be run. Now this is entirely reasonable, as the JVM can hardly run shutdown hooks if you send the JVM a SIGKILL, or whatever the Windows equivalent is.

然而,使用 sys.addShutdownHook 添加的关闭钩子似乎永远不会运行,尽管使用 Runtime.getRuntime.addShutdownHook 运行的那些会运行.

However shutdown hooks added with sys.addShutdownHook never seem to run, although those run with Runtime.getRuntime.addShutdownHook do.

测试 -

scala> val t = new Thread { override def run = println("hi!") }
t: java.lang.Thread = Thread[Thread-4,5,main]

scala> Runtime.getRuntime.addShutdownHook(t)

scala> hi!
george@george-MacBook:~$ scala

(跳过启动信息)

scala> val t = new Thread { override def run = println("hi!") }
t: java.lang.Thread = Thread[Thread-4,5,main]

scala> sys.addShutdownHook(t.run _)
res0: scala.sys.ShutdownHookThread = Thread[shutdownHook1,5,main]

scala> george@george-MacBook:~$

文档说钩子是自动注册的:返回的值可以被忽略"所以不是我们应该添加sys.addShutdownHook返回的线程(无论如何会导致IllegalArgumentException:Hook 先前注册"被抛出).

The documentation says "The hook is automatically registered: the returned value can be ignored" so it's not that we're supposed to add the thread returned by sys.addShutdownHook (and at any rate that causes "IllegalArgumentException: Hook previously registered" to be thrown).

另外,在 addShutdownHook 返回的线程上调用 run 似乎没有做任何事情,这很可疑.

Also, calling run on thread returned by addShutdownHook doesn't seem to do anything, which is suspicious.

推荐答案

addShutdownHook 的类型签名是 ():

The type signature of addShutdownHook is (source):

def addShutdownHook(body: => Unit): ShutdownHookThread

所以,很明显为什么您的代码不起作用.预期是按名称调用的参数 =>Unit 并传递 t.run _,它返回 () =>单位 - 那是完全不同的东西.

So, it is obvious why your code is not working. Expected is a call-by-name argument => Unit and you pass t.run _, which returns () => Unit - that is something entirely different.

Call-by-name 参数在执行之前不会运行,传递 t.run_ 给它意味着在调用 call-by-name 参数时创建了一个函数- 您没有传递函数本身而不是按名称调用参数.

Call-by-name parameters are not run until they are executed, passing t.run _ to it means that a function is created at the time when the call-by-name argument is called - you are not passing the function itself instead of the call-by-name argument.

使用

sys.addShutdownHook(t.run)

相反.或者根本不使用线程,只传递应该执行的代码:

instead. Or don't use the thread at all and just pass the code that should be executed:

sys.addShutdownHook(println("hi"))

这篇关于Scala 关闭挂钩从不运行?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆