Опитвам се да разбера класа ThreadPoolExecutor. Намерих някои крайни променливи, декларирани в този клас и не мога да разбера употребата им.
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
По-горе са крайните променливи и техните двоични и десетични стойности.
След това открих два метода с използването на тези променливи:
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; }
Коментарите преди методите са резултатът, който наблюдавах.
Сега в метод ThreadPoolExecutor#execute(runnable),
Той прави следното изчисление с израз като If fewer than corePoolSize threads are running
int c = ctl.get();
if (workerCountOf(c) < corePoolSize)
Опитвам се да разбера, в който случай стойността на workerCountOf(c) може да бъде по-голяма от corePoolSize. Както можете да видите, първоначалната стойност на ctl е RUNNING.
Освен това има методи за добавяне и намаляване на 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
,
As ((RUNNING+5) & CAPACITY) = 0
.
Може ли някой да ми обясни причината за създаването на тези крайни променливи и тяхното използване?
Как методът workerCountOf() всъщност връща нито един от изпълняваните нишки?
Сигурно пропускам нещо.
Благодаря