In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly explains "what is Android thread pool". Friends who are interested might as well take a look. The method introduced in this paper is simple, fast and practical. Let's let the editor take you to learn what Android thread pool is.
We all know the usage of thread pool. Generally speaking, we first new a ThreadPoolExecutor object, then call execute (Runnable runnable) to pass in our Runnable, and leave the rest to the thread pool. So this time I'll start with the execute method of ThreadPoolExecutor:
Public void execute (Runnable command) {if (command = = null) throw new NullPointerException (); / * Proceed in 3 steps: * * 1. If fewer than corePoolSize threads are running, try to * start a new thread with the given command as its first * task. The call to addWorker atomically checks runState and * workerCount, and so prevents false alarms that would add * threads when it shouldn't, by returning false. * * 2.If a task can be successfully queued, then we still need * to double-check whether we should have added a thread * (because existing ones died since last checking) or that * the pool shut down since entry into this method. So we * recheck state and if necessary roll back the enqueuing if * stopped, or start a new thread if there are none. * 3. If we cannot queue task, then we try to add a new * thread. If it fails, we know we are shut down or saturated * and so reject the task. * / int c = ctl.get (); / / 1. If workerCountOf (c) means that the number of running threads is less than the number of core threads, execute addWork if (workerCountOf (c)
< corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); } //2.如果线程池还在运行状态并且把任务添加到任务队列成功 if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); //3.如果线程池不在运行状态并且从任务队列移除任务成功,执行线程池饱和策略(默认直接抛出异常) if (! isRunning(recheck) && remove(command)) reject(command); //4.否则如果此时运行线程数==0,就直接调用addWork方法 else if (workerCountOf(recheck) == 0) addWorker(null, false); } //5.如果2条件不成立,继续判断如果addWork返回false,执行线程池饱和策略 else if (!addWorker(command, false)) reject(command); } 大致过程就是如果核心线程未满,则直接addWorker(该方法下面会再分析);如果核心线程已满,则尝试将任务加进消息队列中,并再判断如果此时运行线程数==0则调addWorker方法,否则不做任何处理(因为运行的线程处理完自己的任务后会去消息队列中取任务来执行,下面会分析);如果任务队列添加任务失败,那么直接addWorker(),如果addWorker返回false,执行饱和策略,下面我们就来看看addWorker里面做了什么 /** * @param firstTask the task the new thread should run first (or * null if none). Workers are created with an initial first task * (in method execute()) to bypass queuing when there are fewer * than corePoolSize threads (in which case we always start one), * or when the queue is full (in which case we must bypass queue). * Initially idle threads are usually created via * prestartCoreThread or to replace other dying workers. * * @param core if true use corePoolSize as bound, else * maximumPoolSize. (A boolean indicator is used here rather than a * value to ensure reads of fresh values after checking other pool * state). * @return true if successful */ private boolean addWorker(Runnable firstTask, boolean core) { retry: for (;;) { int c = ctl.get(); int rs = runStateOf(c); // Check if queue empty only if necessary. if (rs >= SHUTDOWN & &! (rs = = SHUTDOWN & & firstTask = = null &! WorkQueue.isEmpty ()) return false; for (;) {int wc = workerCountOf (c); / / 1. If the number of running threads is greater than corePoolSize or maximumPoolSize (core is bounded by core threads or maximum threads), return false means addWorker failed if (wc > = CAPACITY | | wc > = (core? CorePoolSize: maximumPoolSize) return false; / / 2. Otherwise, the number of running threads will be + 1 and jump out of the for loop if (compareAndIncrementWorkerCount (c)) break retry; c = ctl.get (); / / Re-read ctl if (runStateOf (c)! = rs) continue retry; / / else CAS failed due to workerCount change Retry inner loop} boolean workerStarted = false; boolean workerAdded = false; Worker w = null; try {/ / 3. Create a Worker object and pass in our runnable w = new Worker (firstTask); final Thread t = w. Thread; if (t! = null) {final ReentrantLock mainLock = this.mainLock; mainLock.lock (); try {/ / thread. / / Back out on ThreadFactory failure or if / / shut down before lock acquired. Int rs = runStateOf (ctl.get ()); 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) {/ / 4. Start the thread t.start (); workerStarted = true;} finally {if (! WorkerStarted) addWorkerFailed (w);} return workerStarted;} Worker (Runnable firstTask) {setState (- 1); / / inhibit interrupts until runWorker this.firstTask = firstTask; this.thread = getThreadFactory (). NewThread (this);} / * Delegates main run loop to outer runWorker. * / 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 {/ / 1. Loop while (task! = null | | (task = getTask ())! = null) {w.lock (); / / If pool is stopping, ensure thread is interrupted; / / if not, ensure thread is not interrupted when firstTask is not empty or getTask is not empty. This / / requires a recheck in second case to deal with / / shutdownNow race while clearing interrupt if ((runStateAtLeast (ctl.get (), STOP)) | (Thread.interrupted () & & runStateAtLeast (ctl.get ()) STOP)) & &! wt.isInterrupted () wt.interrupt () Try {beforeExecute (wt, task); Throwable thrown = null; try {/ / 2. Execute task 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.completedTasksgiving examples; w.unlock ();}} completedAbruptly = false } finally {processWorkerExit (w, completedAbruptly);}}
You can see that the addWorker method mainly determines whether the number of running threads exceeds the maximum number of threads (based on the boundary). If not, create a worker object, where firstTask is the Runnable we passed in. Of course, according to the above execute method, when the condition 4 is satisfied, the incoming firstTask is the thread created by ThreadFactory, and the incoming Runnable is Worker itself, and finally start the thread. So execute the run and runWorker methods here in Worker. In the runWorker method, open a while loop, and execute task when firstTask is not empty or getTask is not empty. Let's take a look at what is done in getTask:
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? / / 1. Will idle threads be eliminated boolean timed = allowCoreThreadTimeOut | | wc > corePoolSize; / / 2.return null means that reclaiming one Worker means eliminating one thread if ((wc > maximumPoolSize | | (timed & & timedOut)) & & (wc > 1 | | workQueue.isEmpty () {if (compareAndDecrementWorkerCount (c)) return null Continue;} try {/ / 3. Wait for the specified time Runnable r = timed? WorkQueue.poll (keepAliveTime, TimeUnit.NANOSECONDS): workQueue.take (); if (r! = null) return r; timedOut = true;} catch (InterruptedException retry) {timedOut = false;}
You can take a look at comments 1 and 2. AllowCoreThreadTimeOut represents whether it is valid for core threads for a certain period of time (default is false). Let's first see if it is ture. At this time, both core threads and non-core threads will wait at 3 places for a certain time (that is, the thread survival time we passed in). If a task is fetched from the task queue during the waiting time, it will be returned for execution, otherwise timeout is true, and continue to 2. Since (timed & timedOut) and workQueue.isEmpty () are both true, null is returned, which means that a thread is recycled. If allowCoreThreadTimeOut is false, it means that the core thread will not be recycled. If the task is not fetched at 3, proceed to 2, and return null will be executed only when wc > corePoolSize or wc > maximumPoolSize. Otherwise, the thread will always loop, which means that the thread is running until it gets a new task from the task queue.
At this point, I believe you have a deeper understanding of "what is Android thread pool". You might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!
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.