복붙노트

[SCALA] 선물은 프로그램 종료 전에 실행되지 않습니다

SCALA

선물은 프로그램 종료 전에 실행되지 않습니다

나는 새로운 스칼라 2.10 선물 기능을 예제를 재현하려고했다. 내가 사용했던 코드는 다음과 같습니다

import scala.concurrent.Future
import scala.concurrent.future

object Test {
    def main(args: Array[String]) {
     println("Test print before future")
     val s = "Hello"
     val f = future {s + " future!"}
     f onSuccess {case v => println(v)}
     println("Test print after future")
    }
}

대신 인쇄 :

Test print before future
Hello future!
Test print after future

그것은 단순히 인쇄 :

Test print before future
Test print after future

나는이 문제를 가지고 왜 어떤 생각? 스칼라 컴파일러의 나의 버전은 2.10.0-20120507입니다.

해결법

  1. ==============================

    1.문제는 당신이 실행하고 있다는 것입니다 누구의 메인 쓰레드 실행할 수있는 작업자 스레드 일 이전에 종료되는 독립 프로그램으로 "안녕하세요 미래를!" 에 println. (스레드는 새로운 선물이 라이브러리 급부상 데몬 스레드입니다).

    문제는 당신이 실행하고 있다는 것입니다 누구의 메인 쓰레드 실행할 수있는 작업자 스레드 일 이전에 종료되는 독립 프로그램으로 "안녕하세요 미래를!" 에 println. (스레드는 새로운 선물이 라이브러리 급부상 데몬 스레드입니다).

    또한 미래 f는 완료 될 때까지 기다려야 (또한 scala.concurrent 단위) 기다리고 있습니다 개체를 사용할 수 있습니다 :

    import scala.concurrent._
    import scala.concurrent.util._
    
    object Test {
      def main(args: Array[String]) {
        println("Test print before future")
    
        val s = "Hello"
        val f = future {s + " future!"}
        f onSuccess {case v => println(v)}
        println("Test print after future")
    
        Await.ready(f, Duration.Inf)
      }
    }
    

    이것은 인쇄 할 수 있습니다 :

    Test print before future
    Test print after future
    Hello future!
    

    또는, "안녕하세요 미래를!"인쇄 할 수 있습니다 스레드 일정에 따라 "미래 후 시험 인쇄"전에.

    마찬가지로, f는 완료 될 때까지 마지막에 println이 같은 다음하기 전에 대기 할 메인 스레드를 강제 할 수 있습니다 :

    import scala.concurrent._
    import scala.concurrent.util._
    
    object Test {
      def main(args: Array[String]) {
        println("Test print before future")
    
        val s = "Hello"
        val f = future {s + " future!"}
        f onSuccess {case v => println(v)}
    
        Await.ready(f, Duration.Inf)        
    
        println("Test print after future")
      }
    }
    

    어떤 인쇄 할 것이다 :

    Test print before future
    Hello future!
    Test print after future
    

    당신을 기다리고를 사용할 때, 노트, 당신은 차단하고있다. 물론 이것은 당신의 기본 응용 프로그램 스레드가 종료되지 않는 것을 확인하기 위해 의미가 있지만, 일반적으로 다른 필요한 경우가 아니면 사용하지 않아야합니다.

    (기다리고 있습니다 개체가이 같은 상황에 필요한 탈출 해치이지만, 느린 덜 병렬 실행이 발생할 수 있습니다 그것의 의미에 대한 걱정없이 응용 프로그램 코드를 통해 그것을 사용. 당신은 콜백 일부 지정된 순서대로 실행되는 것을 보장해야하는 경우를 위해 예를 들어, 같은 미래에 andThen 및지도 방법 등의 다른 대안이있다.)

  2. ==============================

    2.나는 여기에 문제가 타이밍이라고 생각합니다. 대부분의 아마 당신의 미래 코드는 별도의 데몬 스레드에서 실행됩니다. 나는 매우 빠르게 해당 응용 프로그램의 마감이 데몬 스레드 (응용 프로그램이 마무리 데몬 스레드를 기다리지 않습니다)가 제대로 실행하는 데 충분한 시간이 없어 생각합니다. 그러나이 또한 매우 시스템에 의존하는 행동. 나에게는 인쇄 :

    나는 여기에 문제가 타이밍이라고 생각합니다. 대부분의 아마 당신의 미래 코드는 별도의 데몬 스레드에서 실행됩니다. 나는 매우 빠르게 해당 응용 프로그램의 마감이 데몬 스레드 (응용 프로그램이 마무리 데몬 스레드를 기다리지 않습니다)가 제대로 실행하는 데 충분한 시간이 없어 생각합니다. 그러나이 또한 매우 시스템에 의존하는 행동. 나에게는 인쇄 :

    Test print before future
    Test print after future
    Hello future!
    

    다음 종료는 (I 스칼라 2.10.0-M3를 사용하고 있습니다). 단지 몇 초 동안 잠 주요 실행 스레드를 넣어 여부 안녕하세요 미래를 볼 - 당신은 그것을 테스트하기 위해 다음과 같은 시도 할 수 있습니다! 인쇄는 다음과 같습니다

    import scala.concurrent.Future
    import scala.concurrent.future
    
    object Test {
        def main(args: Array[String]) {
            println("Test print before future")
    
            val s = "Hello"
            val f = future {s + " future!"}
            f onSuccess {case v => println(v)}
    
            println("Test print after future")
    
            Thread.sleep(3000) 
            println("Test print at the end.")
        }
    }
    
  3. ==============================

    3.스레드 풀의 한계를 치는 : 난 그냥 일반적으로 선물이 실행되지 않는다는 또 다른 가능성이 있음을 추가 할.

    스레드 풀의 한계를 치는 : 난 그냥 일반적으로 선물이 실행되지 않는다는 또 다른 가능성이 있음을 추가 할.

    귀하의 경우에는 아마 다른 사람들이 지적 단순히 타이밍 문제,하지만 미래 참고로이 예제를 고려하십시오

    import scala.concurrent._
    import scala.concurrent.ExecutionContext.Implicits.global
    import scala.concurrent.duration.Duration
    
    
    object FutureDebug {
      def main( args: Array[String] ) {
    
        for (i <- Range(0, 4)) {
          future {
            while (true) {
              Thread.sleep(1000)
              println("I'm doing stupid things in a future")
            }
          }
        }
    
        println("(1) reached? yes")
        val fut = future {
          for (i <- Range(0, 1000)) {
            println("never reached " + i)
          }
          3.14
        }    
        println("(2) reached? yes")
        Await.result(fut, Duration.Inf)
        println("(3) reached? no")
      }
    }
    

    내 컴퓨터에 기본 전역 실행 컨텍스트는 4 스레드가 있습니다. 작업자 스레드가 4 비 감지 미래를 실행 바쁜 때문에, 아래의 미래는 실행되지 않습니다. 하나는 기본 실행 컨텍스트에주의해야하는 이유이며 여러 (정말로) 긴 실행 미래를 처리 할 때 자신의 실행 컨텍스트를 지정하는 것이 가장 좋습니다.

  4. from https://stackoverflow.com/questions/10565475/futures-do-not-run-before-program-termination by cc-by-sa and MIT license