2012-08-16 4 views
3

Clojure에서 동시성에 대해 배우고 있습니다. Clojure에서 제어 흐름을위한 시간 - ScheduledThreadPoolExecutor의 함정?

나는 (스튜어트 세라?) 주장에 달렸다 http://dev.clojure.org/display/design/Scheduled+Events에서 진술 :

이 가 가 차단 또는 Java 상호 운용성없이 제어 흐름을위한 시간을 사용할 수 없습니다
  • Clojure의 기능
  • 자바 상호 운용성 (로 스케줄이)입니다
      나는 이러한 주장을 이해하고 친절하게 설명, 체육을 요청하지 않는

    스레드 로컬 바인딩을 인식하지 예를 들면. 구체적으로 :

    • ScheduledThreadPoolExecutor의 현재 상태는 그대로입니다. 새로운 (녹색) 스레드를 시작하기 때문에 스레드 별 바인딩이 어쨌든 수행 할 것으로 예상하지는 않습니다.
    • 정상적인 Clojure 함수를 예약 할 수 있습니다. 그래서 어휘 적으로 닫힌 컨텍스트로 원하는 바인딩을 보내는 것을 막을 수 있습니까?

    감사합니다.

  • 답변

    4

    좋아, 알았어.

    당신이 이것을 시도한다고 가정

    (def pool (atom nil)) 
    
    (defn- thread-pool [] 
        (or @pool 
         (reset! pool (ScheduledThreadPoolExecutor. 1)))) 
    
    (def ^:dynamic *t* 0) 
    
    (binding [*t* 1] 
        (future (println "first example:" *t*))) 
    
    (binding [*t* 1] 
        (.schedule (thread-pool) (fn [] (println "second example:" *t*)) 0 
           TimeUnit/SECONDS)) 
    
    (binding [*t* 1] 
        (.schedule (thread-pool) (bound-fn [] (println "third example:" *t*)) 0 
           TimeUnit/SECONDS)) 
    

    가 출력 될 것입니다 :

    첫 번째 경우에
    first example: 1 
    second example: 0 
    third example: 1 
    

    가 미래 매크로 민간 기능 바인딩 컨베이어 fn을, 함께 몸을 감싸는 어휘 범위에서 호출 스레드의 바인딩 프레임을 보존하고 래핑 된 함수를 호출하기 전에이를 복원합니다.

    세 번째 경우 bound-fn은 호출 스레드의 바인딩을 프레임에 푸시하고 함수 본문을 실행 한 다음 바인딩을 팝합니다.

    두 번째 경우에는 아무도 스레드별로 바인딩을 저장하지 않습니다. Java 클래스는 확실히 이들에 대해 알지 못하므로 t Var의 루트 값으로 떨어집니다.

    나는 누군가가이 흥미로운 것을 알기를 바랍니다.

    관련 문제