2014-09-16 1 views
4

사용할 때 제대로 프로그램을 종료하는 방법 : 응용 프로그램이 종료 정상적으로 반면, 첫 번째 경우에Scalaz 선물과 시간 제한 기능이 예상대로 작동

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) 
} 

:

object Planexecutor extends App {  
    import scalaz.concurrent.Future 
    import scala.concurrent.duration._ 

    val f = Future.apply(longComputation) 
    val result = f.run 
    println(result) 
} 

이하지 않습니다 두 번째 경우에는 그렇지 않습니다. 그러나 두 버전 모두 결과 값을 제대로 인쇄합니다.

이것은 버그입니까, 아니면 이해할 수없는 것이 있습니까?

답변

5

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) 

는 UPDATE : 그것은 아주 간단한 수정 그래서 나는을 만들어졌다