>source

웹사이트의 모든 사용자에게 대량 이메일을 보내야 합니다. 발송되는 각 이메일에 대해 스레드 풀을 사용하고 싶습니다. 현재 값을 다음과 같이 설정했습니다.

<property name="corePoolSize" value="500" /><property name="maxPoolSize" value="1000" />

이 둘의 차이점은 무엇이며 규모는 어떻게 됩니까? 현재 나는 대략. 10000명의 사용자.

"각 이메일에 대한 스레드 풀"이 아니라 "각 이메일에 대한 스레드"를 의미한다고 생각합니다.

skaffman2021-09-20 06:40:59
  • 답변 # 1

    우리는 이미 많은 답변을 가지고 있고 충분할 것입니다. 그러나 나는 항상 격일로 혼란스러웠습니다. 그래서 나는 이것을 관련시키기 위해 실시간 예를 생각해 냈습니다!

    이를 얻는 간단하고 효율적인 방법은 자신이 은행에 있다고 생각하는 것입니다.

    창문이 있는데도 줄을 서본 적이 있습니까? 사용 가능한 현금 창구가 있는 경우 은행은 왜 고객을 대기열에 두어야 합니까? 바로 그 경우다.코어 풀 크기. 사용하지 않은 스레드가 있으면 새 작업이 직접 할당됩니다.

    사용 가능한 창(코어 풀 크기)이 가득 차면 고객은 대기열에서 기다려야 합니다. 여기는대기열 용량사진에 온다! 새 작업은 대기열에 추가할 작업이 없을 때까지 계속 대기열에 있습니다.

    대기실이 손님으로 가득 차 있다면? 은행은 고객(작업) 수가 급증하면 새로운 현금창구를 할당/개방할 수 있습니다. 그들은 3개의 예비금을 더 가지고 있었다. 여기 온다최대 풀 크기문맥.

    이 창(스레드)이 모두 채워지면 Bank는 더 이상 새로운 고객(작업)을 서버할 수 없습니다. 동의하다? 그리고 이후로는 새로운 작업이 허용되지 않습니다!

  • 답변 # 2

    @skaffman이 지적한 것 외에도 다음은 이러한 크기가 어떻게 활용되는지 더 명확하게 보여줍니다.

    모든BlockingQueue제출된 작업을 전송하고 보류하는 데 사용할 수 있습니다. 이 대기열의 사용은 풀 크기 조정과 상호 작용합니다.

    <울>
  • 미만인 경우corePool크기스레드가 실행 중이고집행자항상 대기열에 추가하는 것보다 새 스레드를 추가하는 것을 선호합니다.
  • 만약corePool크기또는 더 많은 스레드가 실행 중일 때집행자새 스레드를 추가하는 것보다 항상 요청을 대기열에 추가하는 것을 선호합니다.
  • 요청을 대기열에 넣을 수 없는 경우 초과하지 않는 한 새 스레드가 생성됩니다.최대 풀 크기, 이 경우 작업이 거부됩니다.
  • 답변 # 3

    모두가 명확하게 설명한 것이 맞습니다. 여기서 주의해야 할 몇 가지 사항은 코어 풀과 큐에 대해 항상 제한된 크기를 가져야 한다는 것입니다. core-pool-size가 매우 높으면 모든 요청에 ​​대해 max-pool-size에 도달할 때까지 새 스레드가 생성되기 때문에 풀의 많은 스레드가 특정 기간 동안 사용되지 않은 상태로 남아 있을 가능성이 높습니다.

    그러나 머신이 동시에 많은 수의 요청에 직면하게 된다면 머신 크기가 충분하다는 점도 고려해야 합니다. 예:

    머신 크기가 1GB이고 대기열 용량이 Integer.MAX_VALUE인 경우 JVM GUI 도구에서 모니터링할 수 있는 OutOfMemory 때문에 특정 시점에서 시스템이 요청을 거부하기 시작할 가능성이 높습니다.

  • 답변 # 4

    다음은 스레드 생성에 대한 Sun의 간단한 규칙입니다.

    1. 스레드 수가 다음보다 적은 경우corePool크기, 새 스레드를 만들어 새 작업을 실행합니다.
    2. 스레드 수가 같거나 더 많은 경우corePool크기, 작업을 대기열에 넣습니다.
    3. 대기열이 가득 차서 스레드 수가 다음보다 적은 경우최대 풀 크기, 작업을 실행할 새 스레드를 만듭니다.
    4. 대기열이 가득 차고 스레드 수가 다음보다 크거나 같은 경우최대 풀 크기, 작업을 거부합니다.

    이 ThreadExecutor 프로그램에서 이 이상한 동작을 설명할 수 있습니까? 여기에서 언급한 4가지 경우를 따르지 않습니다.

    Steve2021-09-20 12:55:23
  • 답변 # 5

    corePoolSize또는 maxPoolSize값을 높이는 것보다 queueCapacity값을 높이는 것이 좋습니다. 이 두 속성(*PoolSize)은 실행할 풀 수이지만 각 메시지는 queueCapacity에서 고려됩니다.

    <property name="corePoolSize" value="5" /><property name="maxPoolSize" value="10" /><property name="queueCapacity" value="1000" /><property name="waitForTasksToCompleteOnShutdown" value="true"/>

    10000명의 사용자가 보내야 하므로 1000 * 10 (maxPoolSize)= 10000이지만 각 스레드에 대해 1000이 무거우면 poolSize를 늘리는 것을 고려할 수 있습니다.

    대기열 용량은 기본적으로 Integer.MAX_VALUE이므로 늘릴 필요가 없습니다!

    rlm2021-09-20 06:40:59

    @rlm, 이 경우 더 이상 스레드가 생성되지 않고 스레드는 corePoolSize에 유지됩니다.

    Pant2021-09-20 13:09:47

    @BillMan, taynguyen의 대답은 태양 구현이지만 질문하는 개발자는 "Spring ThreadPoolTaskExecutor"에 대해 이야기합니다. "Spring ThreadPoolTaskExecutor"에서 큐 용량은 정수 최대 값과 최대 풀 크기로 초기화되어 "풀이 임의의 수의 동시 작업(skaffman)을 수용할 수 있도록 허용"합니다.

    rlm2021-09-20 17:00:11

    @rlm: 기본 구성은 최대 풀 크기와 대기열 용량이 무제한인 코어 풀 크기 1입니다. 이것은 Executors.newSingleThreadExecutor()와 대략 동일합니다.

    BillMan2021-09-20 17:14:35
  • 답변 # 6

    :

    <블록 인용>

    새 작업이 제출되고 [...] 보다 적은corePool크기스레드는 실행 중이면 새 스레드가 생성됩니다. 다른 경우에도 요청을 처리합니다. 작업자 스레드가 유휴 상태입니다. 만일 거기에 이상corePool크기하지만 미만최대 풀 크기실행 중인 스레드, 새 스레드는 다음 경우에만 생성됩니다. 대기열이 가득 찼습니다. 설정하여corePool크기그리고최대 풀 크기동일하게 고정 크기를 생성합니다. 스레드 풀. 설정하여최대 풀 크기본질적으로 다음과 같은 무한한 가치정수.MAX_VALUE, 당신은 허용 임의의 것을 수용할 수 있는 풀 동시 작업 수.

    특정 상황에서 500개의 이메일을 동시에 보내는 것은 무의미하고 메일 서버를 압도할 것입니다. 많은 수의 이메일을 보내야 하는 경우 단일 스레드를 사용하여 한 번에 하나씩 파이프로 보내십시오. 메일 서버는 500개의 개별 연결보다 훨씬 더 원활하게 이를 처리합니다.

    이 ThreadExecutor 프로그램에서 이런 일이 일어나는 것을 볼 수 없습니다. 여기서 무엇이 다른지 설명할 수 있습니까?

    Steve2021-09-20 12:55:23
  • 답변 # 7

    corePoolSize풀에서 사용하는 최소 스레드 수입니다. 숫자는 최대 증가할 수 있습니다.최대 풀 크기. 부하가 줄어들면 풀이 다시 축소됩니다.corePool크기.

    이메일을 보내는 것은 I/O 바운드 작업인 것 같습니다. 스레드가 500개 있다고 해서 더 빨라질 것이라고는 생각하지 않습니다.

  • 이전 java : ❏ 봄 부팅에서 YAML 파일을 구성하는 방법은 무엇입니까?
  • 다음 Java가 컴퓨터에서 갑자기 발견되지 않음