복붙노트

[SCALA] scala.concurrent.blocking - 실제로 무엇을합니까?

SCALA

scala.concurrent.blocking - 실제로 무엇을합니까?

스칼라 실행 컨텍스트, 기본 스레딩 모델과 동시성의 주제를 배우면서 나는을 보냈습니다. 당신은 "런타임 동작을 조정"scala.concurrent.blocking 않고 scaladoc에 설명 된대로 "성능이나 피할 교착 상태를 향상시킬 수 있습니다"어떤 방법으로 설명 할 수 있습니까?

문서에서는, Awaitable를 구현하지 않습니다 await를 API에 대한 수단으로 제공됩니다. (아마 또한 단지 오래 실행되는 계산은 포장해야 하는가?).

그것은 실제로 수행하는 것이 무엇입니까?

소스를 통해 다음 쉽게 그 비밀을 배신하지 않습니다.

해결법

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

    1.차단이 포함 된 코드 차단 및 기아 스레드으로 이어질 수 있다는 ExecutionContext에 대한 힌트 역할을하기위한 것입니다. 이 스레드 풀을 기아를 방지하기 위해 새로운 스레드를 생성 할 수있는 기회를 제공 할 것입니다. 이것은 "런타임 동작을 조정"을 의미하는 것이다. 그것은 마법 아니지만, 그리고 모든 ExecutionContext에 작동하지 않습니다.

    차단이 포함 된 코드 차단 및 기아 스레드으로 이어질 수 있다는 ExecutionContext에 대한 힌트 역할을하기위한 것입니다. 이 스레드 풀을 기아를 방지하기 위해 새로운 스레드를 생성 할 수있는 기회를 제공 할 것입니다. 이것은 "런타임 동작을 조정"을 의미하는 것이다. 그것은 마법 아니지만, 그리고 모든 ExecutionContext에 작동하지 않습니다.

    이 예제를 생각해 봅시다 :

    import scala.concurrent._
    val ec = scala.concurrent.ExecutionContext.Implicits.global
    
    (0 to 100) foreach { n =>
        Future {
            println("starting Future: " + n)
            blocking { Thread.sleep(3000) }
            println("ending Future: " + n)
        }(ec)
    }
    

    이 기본 전역의 ExecutionContext를 사용하고 있습니다. -이 같은 코드를 실행, 당신은 100 개 선물은 모두 즉시 실행되는 것을 알 수 있습니다,하지만 당신은 차단 제거하면, 그들은 한 번에 몇 가지를 실행합니다. 기본 ExecutionContext에 새로운 스레드를 산란하여 (예 :로 표시) 호출을 차단에 반응 할 것이다, 따라서 선물을 실행 오버로드되지 않습니다.

    이제 4 개 스레드의 고정 풀 예를 보면 :

    import java.util.concurrent.Executors
    val executorService = Executors.newFixedThreadPool(4)
    val ec = ExecutionContext.fromExecutorService(executorService)
    
    (0 to 100) foreach { n =>
        Future {
            println("starting Future: " + n)
            blocking { Thread.sleep(3000) }
            println("ending Future: " + n)
        }(ec)
    }
    

    이 ExecutionContext에 새로운 스레드를 산란 처리하기 위해 내장되지 않으며, 내 차단 코드 차단에 둘러싸여 너무도으로, 당신은 여전히 ​​한 번에 최대 4 개 선물을 실행할 것을 볼 수 있습니다. 그래서 우리가 말할 이유는 "성능이나 피할 교착 상태를 개선 할 수있다"고 - 그것을 보장 아니에요. 우리는 후자의 ExecutionContext에서 볼 때, 그것은 전혀 보장 아니에요.

    그것은 어떻게 작동합니까? 링크 된 바와 같이, 차단이 코드를 실행합니다 :

    BlockContext.current.blockOn(body)(scala.concurrent.AwaitPermission)
    

    BlockContext.current는 여기에서 보이는 현재의 스레드에서 BlockContext를 검색합니다. BlockContext은 일반적으로 BlockContext이 혼합 특성과 단지 스레드입니다. 소스에서 볼 수 있듯이, 그것은 중 하나의 ThreadLocal에 저장하거나이 발견되어 있지 않은 경우, 현재의 스레드 밖으로 일치하는 패턴이다. 현재 스레드가 BlockContext없는 경우, 다음 DefaultBlockContext가 대신 사용됩니다.

    다음으로, blockOn 현재 BlockContext 호출됩니다. 그것의 구현은 ExecutionContext에 그것을 처리하는 방법에 따라 달라집니다 있도록 blockOn는 BlockContext에서 추상적 인 방법이다. 우리가 DefaultBlockContext의 구현을 보면 (현재의 thread가 BlockContext하지 않을 때), 우리는 blockOn 실제로 아무 것도 존재하지 않습니다 것을 알 수있다. 아무것도 특별한 전혀 수행하고, 코드가없는 부작용으로,있는 그대로 실행될 때 비 BlockContext 수단에 차단 사용 그래서.

    무엇 BlockContexts있는 스레드에 대한? 예를 들어, 여기에 본 글로벌 맥락에서, blockOn 아주 조금 더 않습니다. 더 깊이 파고, 같은 코드에서 정의 된 DefaultThreadFactory가 ForkJoinPool에 새 스레드를 산란에 사용되는로는, 후드 아래 ForkJoinPool를 사용하고 있음을 볼 수 있습니다. BlockContext (스레드)에서 blockOn의 구현없이, ForkJoinPool 당신에게있는 거 차단을 모르는 및 응답에 더 많은 스레드를 생성하려고하지 않습니다.

    스칼라의 기다리고 있습니다도 구현 블로킹을 사용합니다.

  2. from https://stackoverflow.com/questions/29068064/scala-concurrent-blocking-what-does-it-actually-do by cc-by-sa and MIT license