Java 및 스레드 풀에 ThreadPoolExecutor에 계약의 원칙을 탐구

I. 서론 스레드 풀

  다음, ① 스레드 풀을 실행할 새 스레드에 직접 비동기 작업을 수행 할 때마다 스레드 풀 시간을 사용하지 않고, 비동기 많은 작업을 수행 할 때 더 나은 성능을 제공하기 위해 : 주로 두 가지 문제를 해결하는 스레드 풀을 사용하여 스레드 생성과 소멸은 오버 헤드 요구된다. 풀의 스레드가 다시 사용할 때마다 스레드를 다시 생성하고 파괴하는 비동기 작업을 수행 할 필요가 없습니다; ② 스레드 풀은 동적 스레드의 수를 제한 할 수 있습니다와 같은 자원 제한 및 관리 도구를 제공하는 새 스레드 등등.

둘째, 가능한 ThreadPoolExecutor 클래스

1, 우리는 간단히 멤버 변수에있는 ThreadPoolExecutor의 일부를보고 의미는 나타냅니다

   정수형의 CTL 원자 변수의 멤버 변수 상속에있는 ThreadPoolExecutor AbstractExecutorService은 스레드의 수는 전술 한 바와에 유사한 스레드 풀 및 스레드 풀의 상태를 기록하는 읽기 쓰기 잠금 둘을 보유하는 변수를 사용하여 정보의 종류. 여기에 (정수 32 본) 스레드 풀 29 스레드의 3 CTL 높은 숫자 뒤에, 스레드 풀의 상태를 나타냄. 소스 코드에서의 멤버 변수를 다음과 같이은 가능한 ThreadPoolExecutor

1  // (3 비트)는 스레드 풀의 상태를 나타내고, (하위 29 비트) 스레드 풀의 스레드 수를 나타내고,
 2  // 기본 주행 상태, 스레드 풀의 수는 0이다 
. 3  개인  최종 AtomicInteger CTL의 = 새로운 새 AtomicInteger (ctlOf (주행, 0 ))
 . 4  
. 5  // 스레드 수가 후 -3 다음 특정 플랫폼에 의해 표현 된 비트의 정수 나머지 비트의 수를 나타내고,
 6  // 상기 Integer.SIZE = 32 실의 하부 29 비트들의 수는 다음 -3으로 표시된다 
.도 7  개인  정적  최종  INT = COUNT_BITS Integer.SIZE 3 -. ;
 . 8  
. 9  // 최대 수의 스레드 (로우 29) 00011111111111111111111111111111 (1 << 29-1) 
10  개인  정적  최종  INT=에서는 용량 (COUNT_BITS << 1이다.) - 1이다. ]
 (11).  
(12)가  // 스레드 풀 상태 (하이 상태 3 스레드 풀을 나타낸다)
 (13)가  // 111 00,000,000,000,000,000,000,000,000,000 
14  개인  정적  최종  INT 주행 = -1 << COUNT_BITS]
 15  
16  // 000 00,000,000,000,000,000,000,000,000,000 
. 17  개인  정적  최종  INT 종료 = 0 << COUNT_BITS;
 18이다  
. 19  // 001 00,000,000,000,000,000,000,000,000,000 
20은  개인  정적  최종  INT . 정지 = 1 << COUNT_BITS;
 21 인 
22  // 010 00,000,000,000,000,000,000,000,000,000 
23  개인  정적  최종  INT의 정리 = 2 << COUNT_BITS;
24  
25  // 011 00,000,000,000,000,000,000,000,000,000 
26  개인  정적  최종  INT TERMINATED = 3 << COUNT_BITS;
27  
28  // 获取高3位(运行状态) ==> c & 11100000000000000000000000000000 
29  개인  정적  INT runStateOf ( INT c) { 리턴 c & ~ CAPACITY; }
 30  
31  //하위 29 비트 (스레드의 수)를 얻기 ==> 00011111111111111111111111111111 & C 
32  개인  정적  INT workerCountOf ( INT C) { 반환 C 및 용량}
 33는  
34이다  // 새로운 값 원자 변수 (동작 상태와 스레드의 수) CTL 계산 
35  개인  정적  INT ctlOf ( INT RS, INT WC) { 반환 RS | WC;}

  여기에서 우리는 간단하게 위의 스레드 상태의 의미를 설명 :

  ①RUNNING : 새 작업 및 처리 작업 블로킹 큐에 동의

  ②SHUTDOWN : 새 작업하지만 블로킹 큐의 작업을 처리하는 것을 거부

  ③STOP : 새 작업 및 대기열을 차단하는 작업을 포기하기를 거부하고, 현재 실행중인 작업을 중단합니다

  ④TIDYING : 제로 스레드 풀에 활성 스레드들 중 현재의 번호 (태스크 큐 차단 포함)의 모든 작업을 수행 한 후, 상기 방법은 종료 호출 될

  ⑥TERMINATED : 종료 상태입니다. 메서드 호출 후 상태 종료

매개 변수에 대한 사전 이해와있는 ThreadPoolExecutor의 원칙의 실현 다음 2,

  ①corePoolSize는 : 자동차의 수는 이제 스레드 풀의 핵심입니다

  ②workQueue는 : 블로킹 큐의 작업을 수행 할 작업을 기다리는 보존 (어레이 기반 등 LinkedBlockingQueue를 차단 등 바운드 대기열의리스트에 기초하여, 대기열에 ArrayBlockingQueue 차단 경계)

  ③maximumPoolSize : 스레드 풀 스레드의 최대 수

  ④ThreadFactory : 스레드 공장 만들기

  ⑤RejectedExecutionHandler는 : 정책을 거부, 큐가 가득 때 촬영 제출 전략에 대한 새 작업은 네 가지 주요 전략이있을 때 스레드 풀의 스레드 수는 스레드의 최대 수에 도달 것을 의미한다 : AbortPolicy (던져), CallerRunsPolicy (단지 발신자 스레드가) 작업을 실행하는 곳의 DiscardOldestPolicy은 (차단을 잃고 처리하지 않고 현재 제출 된 작업), DiscardPolicy을 (처리하기 위해 최근 작업을 큐에 직접 폐기)

  ⑥keepAliveTime는 : 스레드의 핵심 수보다 풀 내의 현재의 thread 수, 현재의 thread가 유휴 상태 일 경우 생존 시간은,이 변수는이 스레드의 최대 생존 시간

  ⑦TimeUnit : 단위 시간당의 생존 시간.

  도입 위의 매개 변수에 따라 구현 원리 스레드 풀에서 간단한 보면, 시작점으로 주 처리 흐름 분석 스레드 풀을 새 작업 제출

3, 스레드 풀의 몇 가지 유형의 사용에

  ①newFixedThreadPool : 스레드의 핵심 번호와 스레드의 최대 수를 만들 수 있습니다 nThreads의 스레드 풀 및 차단에 Integer.MAX_VALUE의 큐 길이,이 KeepAliveTime = 0만큼 핵심 스레드가 아닌 스레드의 수는 현재 유휴 상태 지시의 수와 그 회수한다.

공용  정적 (ExecutorService를 인 newFixedThreadPool INT nThreads ) {
     돌아가  새로운 ThreadPoolExecutor에가 (nThreads, nThreads,
                                   0L , TimeUnit.MILLISECONDS,
                                   새로운 에 LinkedBlockingQueue <Runnable를> ()); 
}

 

  ②newSingleThreadExecutor는 : 스레드 풀 1 큐 블록 Integer.MAX_VALUE로 길이 KeepaliveTime은 = 0만큼 코어 스레드 바와 수보다 스레드 수와 현재 스레드를 회수로, 즉 유휴 스레드 코어 수와 스레드의 최대 수를 만들기 스레드.

공용  정적 ExecutorService를 newSingleThreadExecutor는 () {
     돌아가  새로운 FinalizableDelegatedExecutorService 
        ( 새로운 ThreadPoolExecutor에 (1, 1 ,
                                 0L , TimeUnit.MILLISECONDS,
                                 새로운 에 LinkedBlockingQueue <Runnable를> ())); 
}

 

   ③newCachedThreadPoolExecutor은 : 요구에 생성 스레드 풀 스레드 생성 (기껏해야 하나 개의 요소) 수가 0이 초기 스레드가 스레드의 수에 Integer.MAX_VALUE 동기 큐까지이고 큐가 차단되어,이 KeepAliveTime = 60 보여 그 현재 스레드 60하다면 유휴 상태가 복구됩니다. 스레드 풀의이 유형의 특징은 다음과 같습니다 작업 동기화 큐가 동기화 큐는 하나의 작업을 할 수 있습니다, 즉시 실행됩니다 가입

공용  정적 ExecutorService를 newCachedThreadPool는 () {
     돌아가  새로운 ThreadPoolExecutor에 (0 , Integer.MAX_VALUE를,
                                   60L , TimeUnit.SECONDS,
                                   새로운 SynchronousQueue는 <Runnable를> ()); 
}

 

   4, ThreadPoolExecutor에 다른 멤버

  이전 ReentrantLock와 참조 할 수 있습니다 어떤 쓴 잠금 --lock 자바와 동기화에 ReentrantLock와 원칙의 구체적인 실현에 하락하는;

  AQS가 기준 부가되기 전에 상기 정보 자바 큐 동기화에 AQS 도 AQS 분석의 구체적인 구현 원리 함;

  쓰기 다시 참조 할 수 큐의 상태에 대한 기술 협력의 자바 조건 스레드에서 자바 원칙의 실현에 관해서, 협력의 조건 스레드;

// 새로운 작업자 스레드 자성 동작 작업자 제어하기위한 전용 잠금 
개인  최종 ReentrantLock와 mainLock =의 새로운 새 ReentrantLock와 ()의, 

//는 스레드 집합, 작업자가 AQS 인터페이스 Runnable 인터페이스를 상속 작업폭 객체는 스레드가 특정 처리 작업이다
 / / 작업자 AQS을 달성 한 상태 = 0가 취득되지 않는 로크의 현재 상태를 나타내고, 그의 단순 재진입 단독 잠금을 실현하기 위해, 상태 = 1은 록이 획득 된 것을 나타내고,
 // 상태 = -1 기본 상태가되면 작업을 만들어 나타내고 runWorker 전에 중단되는 방법의 동작을 방지하기 위해 제공 만들 때 상태 = -1 
개별  최종 HashSet의 <작업자> 근로자 = 새로운 새 HashSet의 <작업자> (); 

// 종료 조건 해당 로크 큐는 awaitTermination 실 호출이 사용될 때 저장소가 스레드 차단 된 
개인  결승 조건 조건 해지 = mainLock.newCondition에 대한 ();

셋째, 소스 코드 분석

1 공개 무효 실행 (명령의 Runnable)의 구현 방법

  집행 방법의 역할은 스레드 풀 작업 명령 실행에 제출하는 것입니다, 단순히 다음 그림에 따라 읽을 수있는 ThreadPoolExecutor 구현이 생산자 - 소비자 모델과 유사, 사용자가 요소를 생산하는 생산자 스레드 풀 동등한 작업을 추가 할 때, 노동자는 노동자 직접 작업을 수행하거나 소비자 요소의 소비에 해당하는 작업 대기열에서 작업을 얻을 수 있습니다.

. (1)  공개  보이드는 (실행 가능한 명령) {실행
 2      //. (1에게) 태스크가 널인지 NULL이 발생되고, 제 확인하거나 다음 단계를 수행한다 
(3).      IF (명령 == )
 4.          드로  새로운 새 NullPointerException이 ()
 . 5      / (2) / CTL 스레드 풀의 현재 상태와 스레드 풀의 스레드 수의 값을 포함 
6.      INT C = ctl.get ()
 . (7)하기      . (3) // workerCountOf 방법, 즉, 현재의 스레드 풀을 취득하고, 낮은 29 얻는 것이다 스레드 수는 실행하는 새 스레드를 열려면, corePoolSize를보다 적은 
8.      IF (workerCountOf (C) < corePoolSize를) {
 9.          IF (addWorker (명령, true로 ))
 (10)              반환 ;
 . (11)         = C의 ctl.get ();
 12이다      }
 (13)이다      // (4). 스레드 풀 상태를 실행하는 경우, 작업이 차단 큐에 추가된다 
(14)      IF (isRunning는 (C) && workQueue.offer (명령)) {
 15          // ( 4-1) 차 검사, CTL의 값을 얻을 
16          INT =에서 재검사를 ctl.get ();
 17          // (4-2) 현재 쓰레드 풀이 RUNNING 상태에서 해제되지 않은 경우, 대기열에서 작업을 삭제 한 전략을 실행하도록 거부 
18          IF (isRunning는 (에서 다시 확인) &&! 제거 (명령))
 (19)는              거부 (명령)
 (20)          // (4-3) 스레드 풀은 비어있는 경우 그렇지 않은 경우, 스레드 추가 
21          다른  IF (workerCountOf (에서 다시 확인) == 0 )
 22             addWorker ( 널 (null) , 거짓 );
 23      }
 24      // (5) 큐가 가득 차면 새로운 스레드가 실패 할 경우, 새로운 스레드의 구현에 정책을 거부 
25      다른  IF (,! addWorker (명령 거짓 ))
 (26)는          거부를 (명령 )
 27 }

  우리는 디지털 마커의 분석에 따르면, 위의 코드의 실행의 흐름을 보면 :

  (3) 단계는 코어보다 스레드의 수는, 코어 스레드 내부 작업자에게 작업을 추가 할 경우 풀 스레드의 현재 개수, corePoolSize를 미만인 결정한다.

  풀 내의 현재의 thread 수는 구현 (4)에 스레드의 핵심 수보다 큰 경우. (4) 처음이 상태에서, 당신은 상태가 스레드 풀은 이미 비 실행 상태에있을 수 있기 때문에 스레드 풀은 결정하는 데 필요한 작업 큐에 작업을 추가 할 경우, 현재의 thread 풀, 실행중인 상태 인 결정하면서 비 실행 상태 새 작업을 중단 할 필요가있다.

  추가 할 경우 작업 큐 작업은 작업 큐에 작업을 추가 한 후, 스레드 풀의 상태가 변경되었을 수 있기 때문에, 차 교정의 필요성, 성공, 그래서 현재의 스레드 풀가 실행되고 있지 않은 경우 2 차 검사가있을 필요가있다 상태, 작업이 작업 큐에서 제거하고 전략을 실행하는 것을 거부해야하며 차 검증이 성공하면 다음 스레드가 스레드 풀 수없는 경우, 현재의 thread 풀, 비어 있는지 여부를 확인하기 위해 다시 4-3으로 코드를 실행 후, 비어 우리는 새로운 스레드를 생성해야합니다.

  상기 단계 (4)가 생성 부가 작업이 실패하면, 대기열이 가득, 다음 (5)하면 다시 열기 위해 새로운 스레드를 (즉, 그 스레드는 코어 끈없는 아날로그 영상 thread3 및 thread4 위) 작업을 수행하려 스레드 풀 스레드의 현재 수는 새로운 스레드를 열 수 없습니다, 스레드의 최대 수 maximumPoolSize를보다 큰했다. 이 스레드 풀은 풀과 작업 큐가 가득에, 당신이 거부 전략을 수행 할 필요가 속한다.

 

추천

출처www.cnblogs.com/fsmly/p/11007334.html