ThreadPoolExecutor源码分析
程序员文章站
2022-04-19 11:09:34
...
1. 构造函数
它最终调用另外一个构造函数
构造函数主要完成一些初始化的工作,如工作线程数目,保持有效时间,等待队列等。
2.execute()方法分析
在代码注解中说明很清楚,它有两个重要的操作:加入队列或者拒绝。
3.工作线程
工作线程(Worker)主要是来执行用户任务的,它的run方法如下:
再看看runWorker的实现。
有几点注意:
1. beforeExecute(wt, task),afterExecute(task, thrown);是没有实现的,用户可以扩展;
2. task.run(),这里不是start()方法。
4.一道被无数面试官问的问题:shutdown()
线程池shutdown()方法,并不是马上关闭。看看JDK官方文档是如何描述的。
它不会再接受新的线程加入,否则会抛出regjectException。但是它不会马上退出,直到之前
加入的线程执行完成之后才会退出。
另外一个方法shutdownNow()也不能马上关闭线程池,也还是看看JDK官方的描述吧。
看到Attempts没,只是尽力,并不保证。它与shutdown()的区别是,它有返回值,并且它们设置的状态不一样,一个是SHUTDOWN,另一个是STOP。
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), defaultHandler); }
它最终调用另外一个构造函数
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; }
构造函数主要完成一些初始化的工作,如工作线程数目,保持有效时间,等待队列等。
2.execute()方法分析
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(); 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); }
在代码注解中说明很清楚,它有两个重要的操作:加入队列或者拒绝。
3.工作线程
工作线程(Worker)主要是来执行用户任务的,它的run方法如下:
/** Delegates main run loop to outer runWorker */ public void run() { runWorker(this); }
再看看runWorker的实现。
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) { w.lock(); // If pool is stopping, ensure thread is interrupted; // if not, ensure thread is not interrupted. 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 { 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); } }
有几点注意:
1. beforeExecute(wt, task),afterExecute(task, thrown);是没有实现的,用户可以扩展;
2. task.run(),这里不是start()方法。
4.一道被无数面试官问的问题:shutdown()
线程池shutdown()方法,并不是马上关闭。看看JDK官方文档是如何描述的。
/** * Initiates an orderly shutdown in which previously submitted * tasks are executed, but no new tasks will be accepted. */
它不会再接受新的线程加入,否则会抛出regjectException。但是它不会马上退出,直到之前
加入的线程执行完成之后才会退出。
另外一个方法shutdownNow()也不能马上关闭线程池,也还是看看JDK官方的描述吧。
/** * Attempts to stop all actively executing tasks, halts the * processing of waiting tasks, and returns a list of the tasks * that were awaiting execution. These tasks are drained (removed) * from the task queue upon return from this method. */
看到Attempts没,只是尽力,并不保证。它与shutdown()的区别是,它有返回值,并且它们设置的状态不一样,一个是SHUTDOWN,另一个是STOP。
上一篇: 刘备为什么对法正如此喜爱和信任 法正到底哪里吸引到刘备
下一篇: 鸡蛋羹一般蒸几分钟