2016-09-03 3 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 

以上は、最終変数とそのバイナリ値と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)方法、

にそれは私がworkerCountOf(C)の値がより大きくなることができ、その場合には、理解しようとしていますIf fewer than corePoolSize threads are running

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

として文を使用して、次の計算をしていますcorePoolSize。 ご覧のとおり、ctlの初期値はRUNNINGです。

また、INCためのメソッドと12月のCTLの値があるアトミック、

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

private boolean compareAndDecrementWorkerCount(int expect) { 
    return ctl.compareAndSet(expect, expect - 1); 
} 

今すぐ((RUNNING+5) & CAPACITY) = 0として5つのスレッドは、workerCountOf(ctl.get()) = 0それでも、

をそうctl = RUNNING + 5を実行している、と言うことができます。

これらの最終変数を作成する理由とその使用方法は誰にも分かりますか?

workerCountOf()メソッドは実際に実行中のスレッドを何も返さないのですか?

私は何かが欠けているはずです。

おかげ

答えて

2

あなたが見ることができるように、Javaはプールとスレッド数の現在の状態の両方を保存するためにint ctlフィールドを使用しています。状態は上位3ビットに格納され、他のすべてのビットはスレッドの数を格納するために使用されます。ビット単位マスクCAPACITYが互いからそれらを分離するために使用される:

  • CAPACITY = 00011111111111111111111111111111
  • ~CAPACITY = 11100000000000000000000000000000したがって

  • ctl & CAPACITYは、下位29ビットを保持し、上位3ビットをゼロ。結果は現在のスレッド番号である
  • ctl & ~CAPACITYは、他のすべての上位3ビットと0を保持します。結果はあなたが正しく気づいたようプールの実行状態

で、5つのスレッドで実行されているプールは、バイナリ表現111000...000101を持っているctl = (RUNNING + 5)を持っています。したがって、CAPACITYマスクを適用すると、最も高い3ビットがゼロになり、000000...000101という値が与えられます.05ではなく5です。

+0

私の間違いを修正するためのありがとう@Andrew。また、このクラスがどのようにバイナリ表現を利用しているのか理解してくれてありがとう。 –

+0

@ akash777.sharma、私の喜び –

+0

あなたは雄牛目をキャッチしました。 –

関連する問題