In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-24 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article introduces the relevant knowledge of "what is the implementation principle of Java thread pool". In the operation of actual cases, many people will encounter such a dilemma, so let the editor lead you to learn how to deal with these situations. I hope you can read it carefully and be able to achieve something!
Thread pool status
First, recognize two parameters that run through the thread pool code:
RunState: thread pool running status workerCount: number of worker threads
The thread pool uses a 32-bit int to hold both runState and workerCount, of which the top 3 bits are runState and the remaining 29 bits are workerCount. RunStateOf and workerCountOf are used repeatedly in the code to get runState and workerCount.
Private final AtomicInteger ctl = new AtomicInteger (ctlOf (RUNNING, 0)); private static final int COUNT_BITS = Integer.SIZE-3 leading private static final int CAPACITY = (1 = STOP | | workQueue.isEmpty ()) {decrementWorkerCount (); return null;} int wc = workerCountOf (c); / / 2 int wc / 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)) } / / 3try {Runnable r = timed? workQueue.poll (keepAliveTime, TimeUnit.NANOSECONDS): workQueue.take (); if (r! = null) return r out = true;} catch (InterruptedException retry) {timedOut = false;}
Tag 1 checks the status of the thread pool, which shows the difference between SHUTDOWN and STOP. If the thread pool is SHUTDOWN, the tasks waiting in the queue will be processed first; if it is STOP, the tasks in the waiting queue will no longer be processed.
Tag 2 first look at the variable allowCoreThreadTimeOut, false worker idle, will not end; true, if worker idle more than keepAliveTime, it will end. Then there is a very complicated judgment, which is very difficult to translate into a written description. See for yourself. Notice that wc > maximumPoolSize, this may be a run-time call to setMaximumPoolSize, and wc > 1, leaving at least one worker when the waiting queue is not empty.
Mark 3 is the logic for fetching tasks from the waiting queue, which is divided into waiting for keepAliveTime or blocking until there is a task according to timed.
Finally, let's take a look at what needs to be done to end the worker:
Private void processWorkerExit (Worker w, boolean completedAbruptly) {/ / 1if (completedAbruptly) / / If abrupt, then workerCount wasn't adjusteddecrementWorkerCount (); / / 2final ReentrantLock mainLock = this.mainLock;mainLock.lock (); try {completedTaskCount + = w.completedTasks works.remove (w);} finally {mainLock.unlock ();} / / 3tryTerminate (); int c = ctl.get (); / / 4if (runStateLessThan (c, STOP)) {if (! completedAbruptly) {int min = allowCoreThreadTimeOut? 0: corePoolSize;if (min = 0 & &! WorkQueue.isEmpty () min = 1bot if (workerCountOf (c) > = min) return; / / replacement not needed} addWorker (null, false);}}
Normally, workerCount is reduced by one in getTask. At mark 1, use the variable completedAbruptly to determine whether the worker exits abnormally, and if so, you need to add a minus one for workerCount.
Tag 2 adds the number of worker processing tasks to the total and removes it from the collection workers.
Mark 3 attempts to terminate the thread pool, which will be studied later.
When tag 4 deals with the thread pool or RUNNING or SHUTDOWN state, if the worker ends abnormally, it will addWorker directly. If allowCoreThreadTimeOut=true and there are tasks in the waiting queue, keep at least one worker; if the allowCoreThreadTimeOut=false,workerCount is not less than corePoolSize.
To summarize the worker: after the thread pool starts, the worker is created in the pool, wraps the submitted Runnable task and executes, waits for the next task, and ends when it is no longer needed.
Closure of thread pool
The closure of the thread pool is not a matter. Worker is in different states in the pool, and the "aftermath" of worker must be arranged in order to really release the thread pool. ThreadPoolExecutor provides two ways to close the thread pool:
Shutdown: tasks can no longer be submitted, and tasks that have been submitted can continue to run; shutdownNow: tasks that have been submitted but not executed cannot be run, and tasks that have been submitted but not executed can continue to run, but will be interrupted, and tasks that have been submitted but not executed can be returned.
Public void shutdown () {final ReentrantLock mainLock = this.mainLock;mainLock.lock (); try {checkShutdownAccess (); / / 1 Security Policy Mechanism advanceRunState (SHUTDOWN); / / 2interruptIdleWorkers (); / / 3onShutdown (); / / 4 Null method, subclass implementation} finally {mainLock.unlock ();} tryTerminate (); / / 5}
Shutdown switches the thread pool to the SHUTDOWN state, calls interruptIdleWorkers to request to interrupt all idle worker, and finally calls tryTerminate to attempt to end the thread pool.
Public List shutdownNow () {List tasks;final ReentrantLock mainLock = this.mainLock;mainLock.lock (); try {checkShutdownAccess (); advanceRunState (STOP); interruptWorkers (); tasks = drainQueue (); / / 1} finally {mainLock.unlock ();} tryTerminate (); return tasks;}
ShutdownNow is similar to shutdown in that it switches the thread pool to the STOP state, and the interrupt target is all worker. DrainQueue returns unexecuted tasks that are waiting in the queue.
Both interruptIdleWorkers and interruptWorkers are implemented by traversing the workers set and interrupting the worker that the condition meets.
The above code calls tryTerminate multiple times, which is a way to try to switch the thread pool to the TERMINATED state.
Final void tryTerminate () {for (;;) {int c = ctl.get (); / / 1if (isRunning (c) | | runStateAtLeast (c, TIDYING) | | (runStateOf (c) = = SHUTDOWN & &! WorkQueue.isEmpty ()) return;//2if (workerCountOf (c)! = 0) {/ / Eligible to terminateinterruptIdleWorkers (ONLY_ONE); return;} / / 3final ReentrantLock mainLock = this.mainLock;mainLock.lock (); try {if (ctl.compareAndSet (c, ctlOf (TIDYING, 0)) {try {terminated ();} finally {ctl.set (ctlOf (TERMINATED, 0)); termination.signalAll ();} return;}} finally {mainLock.unlock ();} / / else retry on failed CAS}}
Mark 1 checks the state of the thread pool. In the following cases, return is not necessary for subsequent operations.
RUNNING (still running, cannot be stopped) TIDYING or TERMINATED (no longer running worker) SHUTDOWN and wait for the queue to be non-empty (stop only after execution)
Tag 2 calls interruptIdleWorkers when worker is not empty. You may wonder why it has already been called in shutdown, why it is called again, and only one idle worker is interrupted at a time?
You need to know that when shutdown worker may be in execution, after the execution of blocking in the queue of take, do not know to end, all need to add to call interruptIdleWorkers. Interrupting only one at a time is because when processWorkerExit is executed, tryTerminate is also executed, automatically interrupting the next idle worker.
Tag 3 is the final state switch. The thread pool will first enter the TIDYING state, and then enter the TERMINATED state, in which the empty method terminated is provided for subclass implementation.
After calling the close thread pool method, you need to wait for the thread pool to switch to the TERMINATED state. AwaitTermination checks whether the thread pool enters the TERMINATED state within the specified time. The code is as follows:
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)
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.