Executor framework
은 producer-consumer
패턴을 사용합니다. 위키
, 컴퓨팅
는 생산자 - 소비자 문제 (도 바운스 버퍼 문제로 알려진) 다중 프로세스 동기화 문제의 전형적인 예이다. 이 문제는 큐로 사용되는 공통 고정 크기 버퍼를 공유하는 두 개의 프로세스, 즉 생산자와 소비자 인 을 설명합니다. 제작자의 임무는 데이터를 생성하여 버퍼 에 넣고 다시 시작하는 것입니다. 동시에, 소비자는 데이터를 버퍼 (즉, 버퍼로부터 제거)로 한번에 하나씩 소비한다. 문제는 생산자가 가득 채워져 있고 소비자가 빈 버퍼에서 데이터 을 제거하려고 시도하지 않을 경우 버퍼에 데이터를 추가하려고 시도하지 않는지 확인하는 것입니다. 우리가 다른 ExecutorService framework
구현에 대한보고가있는 경우
는, 더 구체적으로 ThreadPoolExecutor
클래스, 그것은 기본적으로 가지고있는 다음
- 작업이 제출 된 스레드의
- 번호를 개최 큐, 대기열에 제출 된 태스크를 사용합니다.실행 프로그램 서비스의 타입에 기반
, 이들 파라미터는, 예를 들어
,
가
- 고정 스레드 풀은
LinkedBlockingQueue
사용 변경하지 않고 사용자 스레드
- 캐시 스레드 풀 용도 더 구성된 a
SynchronousQueue
및 제출 된 작업 수를 기준으로 0
에서 Integer.MAX_VALUE
사이의 스레드 없음
실행
Runnable
/**
* Class Worker mainly maintains interrupt control state for
* threads running tasks, along with other minor bookkeeping.
* This class opportunistically extends AbstractQueuedSynchronizer
* to simplify acquiring and releasing a lock surrounding each
* task execution. This protects against interrupts that are
* intended to wake up a worker thread waiting for a task from
* instead interrupting a task being run. We implement a simple
* non-reentrant mutual exclusion lock rather than use ReentrantLock
* because we do not want worker tasks to be able to reacquire the
* lock when they invoke pool control methods like setCorePoolSize.
*/
private final class Worker
extends AbstractQueuedSynchronizer
implements Runnable
{
/** Delegates main run loop to outer runWorker */
public void run() {
runWorker(this);
}
final void runWorker(Worker w) {
Runnable task = w.firstTask;
w.firstTask = null;
boolean completedAbruptly = true;
try {
while (task != null || (task = getTask()) != null) {
w.lock();
clearInterruptsForTaskRun();
try {
beforeExecute(w.thread, 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);
}
는 논리 아래에 의존 : ThreadPoolExecutor
public void execute(Runnable command) {
int c = ctl.get();
if (workerCountOf(c) < corePoolSize) {
if (addWorker(command, true))
return;
c = ctl.get();
}
if (isRunning(c) && workQueue.offer(command)) {
int recheck = ctl.get();
if (! isRunning(recheck) && remove(command))
reject(command);
else if (workerCountOf(recheck) == 0)
addWorker(null, false);
}
else if (!addWorker(command, false))
reject(command);
}
의
ThreadPoolExecutor 클래스에서 살펴볼 수 있습니다. – atom
@ BongCon 현재 1 부, 마지막 장.'ThreadPoolExecutor'에 대해 이야기하는 Part 2를 아직 시작하지 않았습니다. Part 2로 바로 넘어 가기가 어렵습니다. – overexchange
실제로 생산자 패턴이 아닙니다. .. 메인 클래스는 실행될 작업을 생성하고 Executor는 그것을 실행하여 작업을 소비합니다 .. –