java 원본 - ThreadPoolExecutor(3)
부서에서 예전에 매우 뛰는 프로그래머가 신기한 코드를 썼는데 ThreadPoolExecutor를 끊임없이 만들고 shutdown을 호출하지 않아서 라인이 너무 많이 넘친다. 그리고 생각해 보면 나는 아직 뛰지 않는 프로그래머이기 때문에 연구와 연구가 비교적 적합하다.이 글은 바로 연못의 퇴출 과정을 설명하는 것이다.자바 원본 - ThreadPoolExecutor(1) 자바 원본 - ThreadPoolExecutor(2) 자바 원본 - ThreadPoolExecutor(3)
shutdown 원본 코드 분석
public void shutdown() {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//
checkShutdownAccess();
// SHUTDOWN, SHUTDOWN
advanceRunState(SHUTDOWN);
// ,
interruptIdleWorkers();
// ThreadPoolExecutor
onShutdown(); // hook for ScheduledThreadPoolExecutor
} finally {
mainLock.unlock();
}
// TERMINATED
tryTerminate();
}
private void advanceRunState(int targetState) {
for (;;) {
int c = ctl.get();
// SHUTDOWN
if (runStateAtLeast(c, targetState) ||
ctl.compareAndSet(c, ctlOf(targetState, workerCountOf(c))))
break;
}
}
// onlyOne false
private void interruptIdleWorkers(boolean onlyOne) {
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
// worker, worker
for (Worker w : workers) {
Thread t = w.thread;
if (!t.isInterrupted() && w.tryLock()) {
try {
// ,
//
//
t.interrupt();
} catch (SecurityException ignore) {
} finally {
w.unlock();
}
}
if (onlyOne)
break;
}
} finally {
mainLock.unlock();
}
}
shutdownNow 소스 분석
shutdown Now () 와 shutdown () 의 대체적인 절차는 비슷하다. 차이점은 다음과 같다.
public List shutdownNow() {
List tasks;
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
//
checkShutdownAccess();
// stop
advanceRunState(STOP);
//
interruptWorkers();
//
tasks = drainQueue();
} finally {
mainLock.unlock();
}
// TERMINATED
tryTerminate();
return tasks;
}
awaitTermination 소스 분석
스레드 탱크 상태가 TERMINATED로 바뀌면 되돌아오거나 시간이 초과됩니다.전체 과정이 자물쇠를 독점하기 때문에 일반적으로 shutdown이나 shutdown Now를 호출해서 사용합니다.
public boolean awaitTermination(long timeout, TimeUnit unit)
throws InterruptedException {
long nanos = unit.toNanos(timeout);
final ReentrantLock mainLock = this.mainLock;
mainLock.lock();
try {
for (;;) {
if (runStateAtLeast(ctl.get(), TERMINATED))
return true;
if (nanos <= 0)
return false;
nanos = termination.awaitNanos(nanos);
}
} finally {
mainLock.unlock();
}
}
작업 스레드 워커 로직 종료
\task를null로 가져오면while 순환을 종료하고finally 부분의 논리를 실행합니다. 즉,processWorkerExit () 방법으로 작업을 수행합니다.
final void runWorker(Worker w) {
Thread wt = Thread.currentThread();
Runnable task = w.firstTask;
w.firstTask = null;
w.unlock(); // allow interrupts
boolean completedAbruptly = true;
try {
// null,
while (task != null || (task = getTask()) != null) {
w.lock();
if ((runStateAtLeast(ctl.get(), STOP) ||
(Thread.interrupted() &&
runStateAtLeast(ctl.get(), STOP))) &&
!wt.isInterrupted())
wt.interrupt();
try {
beforeExecute(wt, task);
Throwable thrown = null;
try {
task.run();
} catch (RuntimeException x) {
thrown = x; throw x;
} catch (Error x) {
thrown = x; throw x;
} catch (Throwable x) {
thrown = x; throw new Error(x);
} finally {
afterExecute(task, thrown);
}
} finally {
task = null;
w.completedTasks++;
w.unlock();
}
}
completedAbruptly = false;
} finally {
//
processWorkerExit(w, completedAbruptly);
}
}
getTask () 방법 (rs>= SHUTDOWN & (rs>= STOP | workQueue.isEmpty ()) 에서 우리는 SHUTDOWN으로 상태를 설정하고 workQueue가 비어 있으면 null로 되돌아와 외부 순환 중 라인의 작업을 종료하고 라인의 종료를 실현합니다.
private Runnable getTask() {
boolean timedOut = false; // Did the last poll() time out?
for (;;) {
int c = ctl.get();
int rs = runStateOf(c);
// Check if queue empty only if necessary.
if (rs >= SHUTDOWN && (rs >= STOP || workQueue.isEmpty())) {
decrementWorkerCount();
return null;
}
int wc = workerCountOf(c);
// Are workers subject to culling?
boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
if ((wc > maximumPoolSize || (timed && timedOut))
&& (wc > 1 || workQueue.isEmpty())) {
if (compareAndDecrementWorkerCount(c))
return null;
continue;
}
try {
Runnable r = timed ?
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
workQueue.take();
if (r != null)
return r;
timedOut = true;
} catch (InterruptedException retry) {
timedOut = false;
}
}
}
참고 문장
자바 중선 스레드 탱크ThreadPoolExecutor 원리 탐구 자바 스레드 탱크ThreadPoolExecutor 사용 및 분석(3) - 정지 스레드 탱크 원리
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
다양한 언어의 JSONJSON은 Javascript 표기법을 사용하여 데이터 구조를 레이아웃하는 데이터 형식입니다. 그러나 Javascript가 코드에서 이러한 구조를 나타낼 수 있는 유일한 언어는 아닙니다. 저는 일반적으로 '객체'{}...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.