JAVA some insight into the thread pool

java thread pool usage here is not to say, just say some of the principles of ThreadPoolExecutor.

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}

corePoolSize: the size of the core pool

maximumPoolSize: The maximum number of threads in the thread pool

keepAliveTime: how long will represent up to maintain the thread does not terminate when the task execution

workQueue: a blocking queue is used to store task waiting to be executed

threadFactory: a thread factory used to create the main thread

handler: represent policies when refused to deal with the task at

My concern is two places

1: The task is how to manage

2: thread pool thread is how to manage, reuse and time-out mechanism to take effect how

With this knowledge basically two main thread pool will be able to know.

WorkQueue seen from the above is used to store task waiting to be executed,

1:任务是如何管理的
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)) {//判断当前线程池是否处于运行状态,及将任务放入workQueue中
        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);
}:

2:那么线程是如何管理的呢?

In addWorker the thread is placed inside the work, and then into the works below.

private boolean addWorker(Runnable firstTask, boolean core) {
...........................
    Worker w = null;
    try {
        w = new Worker(firstTask);
        final Thread t = w.thread;
        if (t != null) {
         ................................
                if (rs < SHUTDOWN ||
                    (rs == SHUTDOWN && firstTask == null)) {
                    if (t.isAlive()) // precheck that t is startable
                        throw new IllegalThreadStateException();
                    workers.add(w);
                    int s = workers.size();
                    if (s > largestPoolSize)
                        largestPoolSize = s;
                    workerAdded = true;
                }
            } finally {
                mainLock.unlock();
            }
            if (workerAdded) {
                t.start();
                workerStarted = true;
            ...........................
}

If you are a new thread in the thread pool is not idle, then creates a new thread and the thread into the thread in the list of workers.

HashSet<Worker> workers = new HashSet<>();

3: how the threads reuse?

t.start();后会调用work里面的run
public void run() {
    runWorker(this);
}
final void runWorker(Worker w) {
    Thread wt = Thread.currentThread();
    Runnable task = w.firstTask;
    w.firstTask = null;
    w.unlock(); // allow interrupts
    boolean completedAbruptly = true;
    try {
        while (task != null || (task = getTask()) != null) {//如果task不为空,那么运行当前的task,如果为空那么在getTask中从workQueue中获取 task 
            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) {
                .......
                } finally {
                    afterExecute(task, thrown);
                }
            } finally {
                task = null;
                w.completedTasks++;
                w.unlock();
            }
        }
        completedAbruptly = false;
    } finally {
        processWorkerExit(w, completedAbruptly);
    }
}

If the task is not empty, then run the current task, get task if it is empty from workQueue in getTask in.

If you currently have idle task, the new task will come directly into the workQueue then work can get to a new task, a new task will be run directly in the idle thread. The method is to use thread pool threads multiplexing.

4: How timeout thread exits?

runWorker里面task = getTask() 从workQueue获取task。我们看看getTask做了是
private Runnable getTask() {
    boolean timedOut = false; // Did the last poll() time out?

    for (;;) {
     ............................

        boolean timed = allowCoreThreadTimeOut || wc > corePoolSize;
        try {
            Runnable r = timed ?
                workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) :
                workQueue.take();
            if (r != null)
                return r;
            timedOut = true;
        } catch (InterruptedException retry) {
            timedOut = false;
        }
    }
}

If it is not the core of the process, it will call workQueue.poll (keepAliveTime, TimeUnit.NANOSECONDS) acquisition task, keepAliveTime is timeout, if a timeout will return null, return to runWorker which, if the task is null, then the task = null! | |! (task = getTask ()) = null it is false, it will go directly to the processWorkerExit inside, which carried out the exit thread.

final void runWorker(Worker w) {
   .......................
    try {
        while (task != null || (task = getTask()) != null) {
        .....................
        }
        completedAbruptly = false;
    } finally {
        processWorkerExit(w, completedAbruptly);
    }
}

 

private void processWorkerExit(Worker w, boolean completedAbruptly) {
    ......................
    try {
        completedTaskCount += w.completedTasks;
        workers.remove(w);
    } finally {
        mainLock.unlock();
    }
    .......................
    }
}

ProcessWorkerExit w in the works removed from the inside, because the thread of the run is over, so the thread will be recovered out of a gc.

If you have questions, please point it out, thank you

Guess you like

Origin blog.csdn.net/dxh040431104/article/details/93365893