2016-09-03 7 views
3

ThreadPoolExecutor 클래스를 이해하려고합니다. 그 클래스에서 선언 된 일부 최종 변수를 발견하여 사용법을 이해할 수 없습니다.ThreadPoolExecutor의 workerCountOf() 메소드 java

private final AtomicInteger ctl = new AtomicInteger(ctlOf(RUNNING, 0)); 
private static final int COUNT_BITS = Integer.SIZE - 3;   //29 
private static final int CAPACITY = (1 << COUNT_BITS) - 1; //536870911  00011111111111111111111111111111 

// RUN_STATE is stored in the high-order bits 
private static final int RUNNING = -1 << COUNT_BITS;   //-536870912 11100000000000000000000000000000 
private static final int SHUTDOWN = 0 << COUNT_BITS;   //0    00000000000000000000000000000000 
private static final int STOP  = 1 << COUNT_BITS;   //536870912  00100000000000000000000000000000 
private static final int TIDYING = 2 << COUNT_BITS;   //1073741824 01000000000000000000000000000000 
private static final int TERMINATED = 3 << COUNT_BITS;   //1610612736 01100000000000000000000000000000 

위의 내용은 최종 변수와 2 진수 및 10 진수 값입니다.

private static int runStateOf(int c)  { return c & ~CAPACITY; } // RUN_STATE & ~CAPACITY = RUN_STATE 
private static int workerCountOf(int c) { return c & CAPACITY; } // RUN_STATE & CAPACITY = 0 
private static int ctlOf(int rs, int wc) { return rs | wc; } 

앞서 방법의 코멘트, 내가 관찰 출력 :

은 그럼 사용하여 두 가지 방법이 varibles을 발견했다. 이제 ThreadPoolExecutor#execute(runnable) 방법

,

그것은, If fewer than corePoolSize threads are running

int c = ctl.get(); 
if (workerCountOf(c) < corePoolSize) 

이해하려고로 문을 다음과 같은 계산을하는 경우 workerCountOf (C)의 값보다 클 수 있습니다

corePoolSize. ctl의 초기 값은 RUNNING입니다. 의 inc하는 방법과 원자하는 dec CTL 값이있는 또한

,

private boolean compareAndIncrementWorkerCount(int expect) { 
    return ctl.compareAndSet(expect, expect + 1); 
} 

private boolean compareAndDecrementWorkerCount(int expect) { 
    return ctl.compareAndSet(expect, expect - 1); 
} 
이제 5 개 스레드가 너무 ctl = RUNNING + 5, 실행, 말할 수

,

에도

다음 workerCountOf(ctl.get()) = 0, ((RUNNING+5) & CAPACITY) = 0으로

.

누구나 내게이 최종 변수를 작성한 이유와 사용법을 설명 할 수 있습니까?

workerCountOf() 메서드가 실제로 실행중인 스레드를 반환하지 않는 이유는 무엇입니까?

나는 뭔가를 놓쳤을 것입니다.

감사

답변

2

당신이 볼 수있는 바와 같이, 자바는 풀의 현재 상태와 스레드의 수를 모두 저장하기 위해 int ctl 필드를 사용합니다. 상태는 상위 3 비트에 저장되고 다른 모든 비트는 스레드 수를 저장하는 데 사용됩니다.비트 마스크 CAPACITY는 서로 구분하기 위해 사용된다 :

  • CAPACITY = 00011111111111111111111111111111
  • ~CAPACITY = 11100000000000000000000000000000 따라서

,

  • ctl & CAPACITY 하부 29 개 비트를 유지하고, 높은 3 개의 비트 까진 0; 결과는 현재 스레드 번호입니다.
  • ctl & ~CAPACITY은 상위 3 비트를 유지하고 나머지는 0으로 유지합니다. 결과가 제대로 눈치 풀 실행 상태

이다, 오 개 스레드 실행 풀은 바이너리 표현 111000...000101을 가지고 ctl = (RUNNING + 5)을 가지고 있습니다. 따라서 CAPACITY 마스크를 적용하면 가장 높은 3 비트가 0으로되고 값이 000000...000101이됩니다.이 값은 0이 아니라 5입니다.

+0

고마워요. 또한이 클래스가 이진 표현을 어떻게 활용하는지 이해하게 해줘서 고마워. –

+0

@ akash777.sharma, 내 기쁨 –

+0

당신은 황소 눈을 잡았습니다. –