2014-11-15 4 views
2

sys.addShutdownHook에 대한 scaladoc은 shutdown hooks are NOT guaranteed to be run입니다. 이제 JVM이 SIGKILL을 보내거나 Windows가 무엇이든지간에 JVM이 종료 훅을 거의 실행할 수 없으므로 이는 전적으로 합리적입니다.스칼라 종료 후크가 실행되지 않습니까?

Runtime.getRuntime.addShutdownHook으로 실행되는 경우에도 sys.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 에 의해 돌려 주어지는 thread를 추가 할 필요가있는 (어떤 경우도, "IllegalArgumentException : Hook already registered"가 Throw된다)

또한 addShutdownHook에서 반환 된 스레드에서 실행 호출은 의심 스럽지만 아무 것도하지 않는 것처럼 보입니다.

답변

10

addShutdownHook의 유형 서명은 (source)입니다 : 코드가 작동하지 않는 이유

def addShutdownHook(body: => Unit): ShutdownHookThread 

그래서, 그것은 분명하다. 예상되는 호출 이름이 => Unit이고 t.run _을 전달하면 () => Unit이 반환됩니다. 이것은 완전히 다른 것입니다.

call-by-name 매개 변수는 실행될 때까지 실행되지 않으며 t.run _을 전달하면 call-by-name 인수가 호출 될 때 함수가 작성된다는 것을 의미합니다. 대신 함수 자체를 전달하지는 않습니다 call-by-name 인수.

사용

sys.addShutdownHook(t.run) 

대신. 또는 스레드를 전혀 사용하지 않고 실행해야하는 코드를 전달하면됩니다.

sys.addShutdownHook(println("hi")) 
+0

차이점은 무엇입니까? 이 스칼라를 컴파일하면 클래스 Foo {def bar (a : => Unit) =(); def baz (a :() => Unit) =(); }'두 메소드의 jvm 바이트 코드가 같고 둘 다 Function0을 사용하는 것 같습니다 –

+0

참조 http://stackoverflow.com/questions/4543228/whats-the-difference-between-and-unit – sschaef

+1

@GeorgeSimms 값 폐기에 물린 다 (예 : http://blog.bruchez.name/2012/10/implicit-conversion-to-unit-type-in.html 참조). 그것 때문에, 당신의 셧다운 훅은 실제로 "t.run _' 함수를 생성하고 그것을 버린다"라고 말한다. –

관련 문제