머리말
멀티 스레드 프로그래밍에서는 각 작업에 스레드를 할당하는 것이 비현실적이며 스레드 생성의 오버 헤드 및 리소스 소비가 매우 높습니다. 스레드 풀이 시작되었고 스레드를 관리 할 수있는 강력한 도구가되었습니다. Executor 인터페이스를 통해 Java는 작업 제출 프로세스를 해체하고 프로세스를 실행하는 표준 메소드를 제공하고 실행 가능한 작업을 사용하여 작업을 나타냅니다.
다음으로 Java Thread Pool Framework ThreadPooleExecutor의 구현을 분석하겠습니다.
다음 분석은 JDK1.7을 기반으로합니다
수명주기
ThreadPooleExecutor 에서 상단 3 비트의 용량은 달리기 상태를 나타내는 데 사용됩니다.
1. 실행 : 작업 대기열에서 새로운 작업 및 프로세스 작업을받습니다.
2.Shutdown : 새 작업을받지 못하지만 작업 대기열을 처리하는 작업
3.Stop : 새로운 작업이 접수되지 않았고, 작업 대기열이 해제되지 않으며, 진행중인 모든 작업이 동시에 중단됩니다.
4. TIDYING : 모든 작업이 종료되었으며 작업자 스레드 수는 0입니다.이 상태에 도달하면 종료 ()가 실행됩니다.
5. 종료 : 종료 ()가 실행되었습니다
상태 전환 다이어그램
원자 클래스는 ThreadPooleExecutor의 상태 비트를 나타내는 데 사용됩니다.
개인 최종 AtomicInteger CTL = New AtomicInteger (CTLOF (Running, 0));
스레드 풀 모델
핵심 매개 변수
CorePoolSize : Living Worker 스레드의 최소 수
Maximumpoolsize : 용량별로 제한되는 최대 스레드 수
KeepAliveTime : 해당 스레드의 생존 시간, 시간 단위는 TimeUnit에 의해 지정됩니다.
Workqueue : 작업 대기열, 실행할 작업을 저장합니다
RejectexecutionHandler : 정책 거부, 스레드 풀의 최대 용량은 스레드 풀이 가득 찬 후 트리거됩니다. 용량의 첫 3 비트는 플래그 비트로 사용됩니다.
네 가지 모델
캐시드 스레드 풀 : 캐시 가능한 스레드 풀. 스레드 풀의 현재 크기가 처리 요구 사항을 초과하면 유휴 스레드가 재활용됩니다. 수요가 증가하면 새로운 스레드가 추가 될 수 있습니다. 스레드 풀의 크기에는 제한이 없습니다.
FixedThreadpool : 고정 크기 스레드 풀. 작업을 제출할 때 최대 스레드 풀 수에 도달 할 때까지 스레드가 생성됩니다. 현재 스레드 풀의 크기는 더 이상 변경되지 않습니다.
Singlethreadpool : 작업을 실행할 작업자 스레드가 하나만있는 단일 스레드 스레드 풀입니다. 작업이 대기열에있는 순서대로 작업을 연속적으로 실행하도록 할 수 있습니다. 이 스레드가 비정상적으로 끝나면 작업을 실행하기 위해 새 스레드가 생성됩니다.
ScheduledThreadPool : 고정 크기 스레드 풀이며 타이머와 유사한 지연 또는 시간이 지연된 방식으로 작업을 수행합니다.
작업 실행을 실행합니다
핵심 논리 :
1. 현재 스레드 수 <CorePoolSize, 새 핵심 스레드를 직접 열어 작업 부가 작업자 (명령, True)
2. 현재 스레드 수> = CorePoolSize, 작업이 작업 대기열에 성공적으로 추가됩니다.
1). 스레드 풀의 현재 상태가 실행 중인지 확인
2). 그렇지 않으면 작업이 거부됩니다
3). 그렇다면 현재 스레드 수가 0인지 확인하십시오. 0 인 경우 작업자 스레드를 추가하십시오.
3. 일반 스레드 실행 작업 AddWorker (명령, False)를 켜고 시작하지 않으면 작업을 거부하십시오. 위의 분석에서 스레드 풀 작동의 4 단계를 요약 할 수 있습니다.
1) .poolsize <corepoolsize와 대기열이 비어 있습니다. 제출 된 작업을 처리하기 위해 새 스레드가 생성됩니다.
2) .poolsize == CorePoolsize. 현재 제출 된 작업은 작업 대기열에 들어갑니다. 작업자 스레드는 큐에서 작업 실행을 얻습니다. 현재 큐는 비어 있지 않고 가득 차 있지 않습니다.
3) .poolsize == CorePoolSize 및 대기열이 가득 찼습니다. 제출 된 작업을 처리하기 위해 새 스레드가 생성되지만 Poolsize <MaxPoolsize
4) .poolsize == MaxPoolsize 및 대기열이 가득 찼습니다. 거부 정책이 트리거됩니다.
거부 정책 <br /> 우리는 이전에 과제를 실행할 수 없으면 거부 될 것이라고 언급했다. RejectedExecutionAndler는 거부 된 작업을 처리하기위한 인터페이스입니다. 다음은 네 가지 거부 전략입니다.
AbortPolicy : 기본 정책, 작업 종료, Throw RejecedException
Callerrunspolicy : 예외를 던지지 않고 발신자 스레드에서 현재 작업을 실행합니다.
DiscardPolicy : 정책을 폐기하고, 작업을 직접 버리고, 예외를 던지지 마십시오.
di scandolderspolicy : 가장 오래된 작업을 포기하고 현재 작업을 실행하며 예외를 던지지 마십시오.
스레드 풀의 작업자
작업자는 AbstractQueuedSynchronizer 및 런 가능성을 상속합니다. 전자는 작업자에게 잠금 기능을 제공하고 후자는 작업자 스레드 런 워크 (Worker W)의 주요 방법을 실행합니다 (작업 큐에서 스냅 작업 실행). 작업자 참조는 작업자 컬렉션에서 찾을 수 있으며 Mainlock에 의해 보호됩니다.
Private Final ReintrantLock MainLock = New ReintrantLock ();
개인 최종 해시 세트 <Worker> 작업자 = New Hashset <Worker> ();
핵심 기능 런 워크
다음은 단순화 된 논리입니다. 참고 : 각 작업자 스레드의 실행은 다음 기능을 실행합니다.
Final void Runworker (Worker W) {Thread WT = Thread.CurrentThread (); 실행 가능한 작업 = w.firsttask; w.firsttask = null; while (task! = null || (task = getTask ())! = null) {w.lock (); 전능 이전 (WT, 과제); task.run (); 외과 후 (과제, 던진); w.unlock (); } ProcessWorkEerExit (w, 완료);} 1. getTask ()에서 작업을 받으십시오.
2. 노동자를 잠그십시오
3. 이전에 실행 (wt, task)을 실행합니다. 이는 Sublass에 threadPooleExecutor가 제공하는 확장 방법입니다.
4. 작업을 실행하십시오. 작업자가 첫 번째 작업을 구성한 경우 첫 번째 작업은 먼저 한 번만 실행됩니다.
5. 외과 후 (작업, 던진) 실행;
6. 근로자를 잠금 해제하십시오
7. 획득 된 작업이 NULL 인 경우 작업자를 닫으십시오.
작업 gettask를 얻으십시오
스레드 풀 내부의 작업 대기열은 차단 큐로 구성 중에 전달됩니다.
개인 최종 Blockingqueue <Runnable> Workqueue;
getTask ()는 작업 대기열에서 작업을 가져오고 차단 및 시간 초과 작업 대기를 지원합니다. 네 가지 상황으로 인해 Null이 반환되고 작업자가 폐쇄됩니다.
1. 기존 스레드 수는 최대 스레드 수를 초과합니다.
2. 스레드 풀이 정지 상태에 있습니다
3. 스레드 풀이 종료 상태에 있고 작업 대기열이 비어 있습니다.
4. 스레드 대기 작업 시간 초과 및 스레드 수는 유지 된 스레드 수를 초과합니다.
코어 로직 : 차단 대기열에서 대기 작업을 시간에 타거나 차단합니다. 대기 과제 시간이 지남에 따라 작업자 스레드가 닫히게됩니다.
timed = allowcorethreadtimeout || wc> corepoolsize; runnable r = 타임? workqueue.poll (repualivetime, timeUnit.nanoseconds) : workqueue.take ();
작업을 기다리는 것은 두 가지 경우에 시간이 걸립니다.
1. 코어 스레드가 타임 아웃을 기다리도록 허용합니다.
2. 현재 스레드는 일반 스레드입니다. 현재 WC> CorePoolSize
작업 대기열은 Blockingqueue를 사용하므로 여기에서 확장하지 않습니다. 나중에 자세한 분석을 쓸 것입니다.
요약
ThreadPooleExecutor는 생산자 소비자 모델을 기반으로합니다. 작업 제출 작업은 생산자와 동일하며 실행 작업 스레드는 소비자와 같습니다.
Executors는 ThreadPooleExecutor를 기반으로 스레드 풀 모델을 구성하는 4 가지 방법을 제공합니다. 또한 Thread PooleExecutor를 직접 상속하고 사전에 이전 및 후퇴 방법을 다시 작성하여 스레드 풀 작업 실행 프로세스를 사용자 정의 할 수 있습니다.
구체적인 상황에 따라 경계 큐 또는 무한 큐를 사용하는 것은 작업 대기열의 크기와 스레드 수를 신중하게 고려해야합니다.
거부 정책은 CallerRunspolicy를 사용하는 것이 좋습니다.이 작업은 작업을 포기하거나 예외를 던지지 않고 대신 실행을 위해 발신자 스레드에 작업을 중단합니다.
위는이 기사의 모든 내용입니다. 모든 사람의 학습에 도움이되기를 바랍니다. 모든 사람이 wulin.com을 더 지원하기를 바랍니다.