sys.addShutdownHook
的scaladoc表示shutdown hooks are NOT guaranteed to be run
。现在这是完全合理的,因为如果您将JVM发送到SIGKILL或任何Windows等价物,JVM几乎不能运行关闭挂钩。Scala关机挂钩永不运行?
然而,关机挂钩增加sys.addShutdownHook
似乎永远不会运行,虽然那些与Runtime.getRuntime.addShutdownHook
运行。
测试 -
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!
[email protected]:~$ 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> [email protected]:~$
文档说“钩子自动注册:返回值可以忽略不计”,所以它不是我们”重新添加由sys.addShutdownHook
返回的线程(并且在任何情况下都会导致“IllegalArgumentException:挂钩先前已注册”)。
此外,调用addShutdownHook返回的线程上运行似乎没有做任何事情,这是可疑的。
有什么区别?如果你编译这个Scala类Foo {def bar(a:=> Unit)=(); def baz(a:()=> Unit)=(); }'两个方法的jvm字节码似乎是相同的,都似乎使用Function0 –
请参阅http://stackoverflow.com/questions/4543228/whats-the-difference-between-and-unit – sschaef
@GeorgeSimms您还可以获得被值丢弃咬伤(见例如http://blog.bruchez.name/2012/10/implicit-conversion-to-unit-type-in.html)。正因为如此,你的关机钩实际上是说“创建一个函数't.run _'并把它扔掉”。 –