미래를 위해 미세 조정 된 스레드 풀을 구성하는 방법은 무엇입니까?


80

Scala의 선물용 스레드 풀은 얼마나 큽니까?

내 Scala 애플리케이션은 수백만 개의 future {}s를 생성하며 스레드 풀을 구성하여 최적화 할 수있는 방법이 있는지 궁금합니다.

감사합니다.


슬릭 3.0 사용 자신의 연결과 왜 우리가 자신의 스레드 풀을 관리하는 경우 매끄러운에 대한 암시의 ExecutionContext를 제공해야 할 스레드
라훌 Gulabani을

1
@RahulGulabani에서 "필수 매끄러운"책 :The reason is that map, flatMap methods of Action allows you to call arbitrary code when joining the actions together. Slick cannot allow that code to be run on its own execution context, because it has no way to know if you are going to tie up Slicks threads for a long time.
srzhio

답변:


90

전역 암시 적 ExecutionContext를 가져 오는 대신 Future가 실행될 자체 ExecutionContext를 지정할 수 있습니다.

import java.util.concurrent.Executors
import scala.concurrent._

implicit val ec = new ExecutionContext {
    val threadPool = Executors.newFixedThreadPool(1000)

    def execute(runnable: Runnable) {
        threadPool.submit(runnable)
    }

    def reportFailure(t: Throwable) {}
}

73
좋은 대답은 주어진 Executor에서 직접 인스턴스화 할 수있는 ExecutionContext의 도우미 메서드를 사용하여 상용구를 약간 줄일 수 있습니다. 예 : 암시 적 val ec = ExecutionContext.fromExecutor (Executors.newFixedThreadPool (10))
sksamuel

1
이 모든 것이 좋지만 implicits.global에 대한 스레드에 실제 제한이 있습니까? 그렇다면 application.conf를 통해 akka처럼 구성 할 수 있습니까?
Nick

6
@Nick 예, implicits.global은 CPU 코어 당 하나의 스레드입니다. CPU 바인딩 작업에 최적입니다. 그러나 클래식 블로킹 IO (예 : jdbc)의 경우 성능 재앙입니다.
Ben Hutchison 2014

2
이것을 사용한 후 스레드 풀을 종료하는 호출을 추가해야합니다. 그렇지 않으면 프로그램이 종료되지 않습니다 ... def shutdown () = threadPool.shutdown ()
justinhj

2
왜 "정상적인"경우에 종료되지만 암시 적을 다른 것으로 설정하면 종료되지 않는 이유는 무엇입니까?
hbogert

152

이 답변은 수락 된 답변의 의견 인 monkjack의 것입니다. 그러나이 훌륭한 답변을 놓칠 수 있으므로 여기에 다시 게시하고 있습니다.

implicit val ec = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(10))

스레드 풀 수만 변경해야하는 경우 전역 실행기를 사용하고 다음 시스템 속성을 전달하면됩니다.

-Dscala.concurrent.context.numThreads=8 -Dscala.concurrent.context.maxThreads=8

2
이것은 더 우아한 솔루션입니다
벤 허치슨

값이 5 인 두 가지를 모두 시도했지만 여전히 최대 8 개의 스레드가 동시에 실행되고 있습니다.
micseydel

3

스칼라 선물에서 스레드 풀을 지정하는 가장 좋은 방법 :

implicit val ec = new ExecutionContext {
      val threadPool = Executors.newFixedThreadPool(conf.getInt("5"));
      override def reportFailure(cause: Throwable): Unit = {};
      override def execute(runnable: Runnable): Unit = threadPool.submit(runnable);
      def shutdown() = threadPool.shutdown();
    }

0
class ThreadPoolExecutionContext(val executionContext: ExecutionContext)

object ThreadPoolExecutionContext {

  val executionContextProvider: ThreadPoolExecutionContext = {
    try {
      val executionContextExecutor: ExecutionContextExecutor = ExecutionContext.fromExecutor(Executors.newFixedThreadPool(25))
      new ThreadPoolExecutionContext(executionContextExecutor)
    } catch {
      case exception: Exception => {
        Log.error("Failed to create thread pool", exception)
        throw exception
      }
    }
  }
}
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.