2013-05-03 2 views
13

내가 스칼라 선물은 자바 배경에서 오는 이해하려고 노력하고 있어요 : 나는 당신이 쓸 수 이해 :스칼라 - 선물 및 동시성

val f = Future { ... } 

다음 나는 두 가지 질문이 있습니다

  1. 어떻게 계획이 미래입니다 ? 자동?
  2. 어떤 스케줄러가 사용할 것입니까? Java에서는 스레드 풀 등이 될 수있는 실행 프로그램을 사용합니다.

또한 특정 시간 지연 후에 실행되는 scheduledFuture을 어떻게 얻을 수 있습니까? 감사합니다

+1

미래가 성취 될 때 직접 제어하려는 경우 약속을 사용해야합니다. –

+1

약속은 약간 다르다. 그것들은 본질적으로 집행자의 관점에서 볼 때 '미래'이다. 즉, 어떤 시점에 값을 삽입해야하는 1 회성 (write-once) 컨테이너이다. 호출자/클라이언트는 스케줄을 제어하기 위해'Promise '를 직접 사용할 수있는 방법이 없습니다. –

답변

11

블록 Future.apply (나는 Maciej를 알고있을 것입니다)에 대한 호출을위한 구문 설탕이며 첫 번째 인수로 코드 블록을 전달합니다.

docs for this method을 보면 암시 적으로 ExecutionContext이 걸리는 것을 볼 수 있습니다.이 컨텍스트는 실행 방법을 결정합니다. 따라서 두 번째 질문에 대답하기 위해 암시 적 범위에있는 ExecutionContext에 의해 미래가 실행됩니다 (물론 모호한 경우에는 컴파일 타임 오류입니다).

대부분이 경우 import ExecutionContext.Implicits.global에서 비롯되며 시스템 속성에 따라 조정될 수 있지만 기본적으로 프로세서 코어 당 하나의 스레드가있는 ThreadPoolExecutor을 사용합니다.

그러나 스케줄링은 다른 문제입니다. 일부 유스 케이스의 경우 실행 전 항상 동일한 지연을 적용한 자신의 ExecutionContext을 제공 할 수 있습니다. 하지만 지연을 호출 사이트에서 제어 할 수있게하려면 Future.apply을 예약 할 방법을 알리는 매개 변수가 없으므로 사용할 수 없습니다. 이 경우 작업을 예정된 집행자에게 직접 제출하는 것이 좋습니다.

+0

Yhanks Andrzej - 언제나처럼 도움 : – Bober02

3

의 Andrzej의 대답은 이미 귀하의 질문에 땅의 대부분을 다루고 있습니다. 가치 언급은 스칼라의 "기본"암시 적 실행 문맥 (import scala.concurrent.ExecutionContext.Implicits._)는 java.util.concurrent.Executor그대로이며, 전체의 ExecutionContext의 개념은 매우 얇은 래퍼이지만, 밀접하게 자바의 실행 프로그램 프레임 워크에 일치하는지입니다. 마우가 지적으로 예정된 선물 비슷한 달성을위한

, 당신은 약속을 사용할 수 있고, 제 3 자 스케줄링 메커니즘됩니다.

스칼라 2.10 미래에 내장이에 대한 일반적인 메커니즘을 가지고하지 않는 것은 유감하지만 치명적인 아무것도입니다.

약속 비동기 연산에 대한 핸들이다. 범위가 ExecutionContext이라고 가정하고 val p = Promise[Int]()을 호출하여 만듭니다. 방금 정수를 약속했습니다.
클라이언트는 단순히 스칼라 미래이다, p.future를 호출하여, 성취되고 약속에 따라 미래를 잡을 수 있습니다.
약속을 이행하는 것은 단지 p.successful(3)으로 전화하는 것입니다. 그러면 미래가 완료 될 것입니다.

Play 2.x는 약속과 일반 Java 1.4 타이머를 사용하여 일정을 해결합니다.
Here은 출처에 대한 링크가없는 링크입니다.

하는의도 여기에 소스를 살펴 보자 :

object Promise { 
    private val timer = new java.util.Timer() 

    def timeout[A](message: => A, duration: Long, unit: TimeUnit = TimeUnit.MILLISECONDS) 
       (implicit ec: ExecutionContext): Future[A] = { 
    val p = Promise[A]() 
    timer.schedule(new java.util.TimerTask { 
     def run() { 
     p.completeWith(Future(message)(ec)) 
     } 
    }, unit.toMillis(duration)) 
    p.future 
    } 
} 

이 다음과 같이 사용할 수 있습니다 :이

val future3 = Promise.timeout(3, 10000) // will complete after 10 seconds 

공지 사항이 코드에 Thread.sleep(10000)를 연결보다 훨씬 좋네요하는 스레드를 차단하고 컨텍스트 전환을 강제합니다.

또한이 예에서 유의할 점은 함수의 시작 부분에 val p = Promise...이고 끝에는 p.future입니다. 이는 약속을 할 때 흔히 볼 수있는 패턴입니다. 이것을 받아들이면이 함수가 클라이언트에게 약속을하고 비동기 계산을 수행하여이를 수행합니다.

스칼라 약속에 대한 자세한 내용은 here을 참조하십시오. 그들은 Future.apply 대신 패키지 개체에서 소문자 future 메서드를 사용합니다. 전자는 후자에게 단순히 위임합니다. 개인적으로 나는 소문자 future을 선호합니다.