ThreadPoolExecutor线程的创建与销毁分析
来源:互联网 发布:交行信用卡淘宝有积分 编辑:程序博客网 时间:2024/04/19 23:53
线程池类型
- 固定线程池(newFixedThreadPool)
指定固定大小线程数,如果执行的任务超过线程数,则添加至阻塞队列中,当线程池线程处理完在从队列中进行获取任务进行处理
public static ExecutorService newFixedThreadPool(int nThreads, ThreadFactory threadFactory) { return new ThreadPoolExecutor(nThreads,nThreads,0L,TimeUnit.MILLISECONDS,new LinkedBlockingQueue<Runnable>(),threadFactory); }
- 单例线程池(newSingleThreadExecutor)
指定1个线程数,如果执行的任务超过线程数,则添加至阻塞队列中,当线程池线程处理完在从队列中进行获取任务进行处理
public static ExecutorService newSingleThreadExecutor(ThreadFactory threadFactory) { return new ThreadPoolExecutor(1, 1,0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>()) }
- 缓存线程池(newCachedThreadPool)
不指定固定线程数,最大线程数为Integer.MAX_VALUE,如果执行的任务超过最大线程数,则添加至阻塞队列中,注意此处用的是SynchronousQueue,表明是如果添加一个任务必须等待处理线程取出,否则不能继续添加任务。
public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); }
线程添加
public void execute(Runnable command) { if (command == null) throw new NullPointerException(); 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); }//否则进行继续尝试创建新线程,如果现有线程数大于最大线程数则返回false else if (!addWorker(command, false)) reject(command); } //删除了不必要的代码 private boolean addWorker(Runnable firstTask, boolean core) { retry: for (;;) { int c = ctl.get(); int rs = runStateOf(c); for (;;) { int wc = workerCountOf(c); //判断现有线程数是否大于最大线程数 if (wc >= CAPACITY || wc >= (core ? corePoolSize : maximumPoolSize)) return false; 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 } } }
线程启动
//删除多余代码private boolean addWorker(Runnable firstTask, boolean core) { boolean workerStarted = false; boolean workerAdded = false; Worker w = null; try { final ReentrantLock mainLock = this.mainLock; //创建worker,worker本身也是一个Runnable w = new Worker(firstTask); final Thread t = w.thread; if (t != null) { mainLock.lock(); try { // Recheck while holding lock. // Back out on ThreadFactory failure or if // shut down before lock acquired. int c = ctl.get(); int rs = runStateOf(c); if (rs < SHUTDOWN || (rs == SHUTDOWN && firstTask == null)) { if (t.isAlive()) // precheck that t is startable throw new IllegalThreadStateException(); //添加work值workers,后面的运行数统计、关闭线程池都是基于此workers workers.add(w); int s = workers.size(); if (s > largestPoolSize) largestPoolSize = s; workerAdded = true; } } finally { mainLock.unlock(); } if (workerAdded) { //启动 t.start(); workerStarted = true; } } } finally { if (! workerStarted) addWorkerFailed(w); } return workerStarted; }
线程执行任务
当启动线程后,会调用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 { //先判断当前任务是否不为空,如果不为空则进行当前任务,否则调动getTask()方法,从队列中获取任务 while (task != null || (task = getTask()) != null) { //进行标记表示正在有任务执行,如果这会进行调用shutdown()方法,会判断标记,否则进行中断线程。 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 //如果调用shutdownNow()方法设置stop标记,并且当前线程还未中断,则当前线程自己中断,否则在进行一次判断 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 { //线程退出,这步只有调用shutdown()、shutdownNow()才会执行,否则会在getTask()任务阻塞。 processWorkerExit(w, completedAbruptly); } }
线程池伸缩
private Runnable getTask() { boolean timedOut = false; // Did the last poll() time out? retry: 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; } boolean timed; // Are workers subject to culling? for (;;) { int wc = workerCountOf(c); timed = allowCoreThreadTimeOut || wc > corePoolSize; if (wc <= maximumPoolSize && ! (timedOut && timed)) break; //如果当前线程数大于核心线程数或者设置核心线程数容许超时,那么对现有线程池的线程进行回收 if (compareAndDecrementWorkerCount(c)) return null; c = ctl.get(); // Re-read ctl if (runStateOf(c) != rs) continue retry; // else CAS failed due to workerCount change; retry inner loop } try { Runnable r = timed ? workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS) : workQueue.take(); if (r != null) return r; timedOut = true; } catch (InterruptedException retry) { timedOut = false; } } }
线程池销毁
停止线程池
等正在进行任务执行完,进行停止
public void shutdown() { final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { checkShutdownAccess(); //设置状态 advanceRunState(SHUTDOWN); //遍历所有未执行任务的线程,对其设置中断 interruptIdleWorkers(); onShutdown(); // hook for ScheduledThreadPoolExecutor } finally { mainLock.unlock(); } //在此判断所有任务都已退出,如果退出则设置标记 “TERMINATED” tryTerminate(); }
立即停止线程池
不用等待正在进行任务执行完,立即停止
public List<Runnable> shutdownNow() { List<Runnable> tasks; final ReentrantLock mainLock = this.mainLock; mainLock.lock(); try { checkShutdownAccess(); //设置状态STOP状态 advanceRunState(STOP); ////遍历所有任务的线程(包括正在执行任务的线程),对其设置中断 interruptWorkers(); //返回等待执行的任务列表 tasks = drainQueue(); } finally { mainLock.unlock(); } //在此判断所有任务都已退出,如果退出则设置标记 “TERMINATED” tryTerminate(); return tasks; } private List<Runnable> drainQueue() { BlockingQueue<Runnable> q = workQueue; List<Runnable> taskList = new ArrayList<Runnable>(); //尝试把队列中任务移动taskList q.drainTo(taskList); //这一步判断主要针对DelayQueue,因为drainTo只返回到期的任务,所以需要单独处理 if (!q.isEmpty()) { for (Runnable r : q.toArray(new Runnable[0])) { if (q.remove(r)) taskList.add(r); } } return taskList; }
阅读全文
0 0
- ThreadPoolExecutor线程的创建与销毁分析
- android线程的创建与销毁
- Android线程的创建与销毁
- Android线程的创建与销毁
- Android线程的创建与销毁
- linux内核线程的创建与销毁
- linux内核线程的创建与销毁
- linux内核线程的创建与销毁
- Android线程的创建与销毁
- Android线程的创建与销毁
- Android线程的创建与销毁
- Android线程的创建与销毁---转载
- Android线程的创建与销毁.
- Android线程的创建与销毁
- 内核中线程的创建与销毁
- Android线程的创建与销毁
- Android线程的创建与销毁
- Android线程的创建与销毁
- C~K要找女朋友了!!!
- File类及IO流
- 一次由查询转换引起的性能问题的分析
- 本地光缆未连接(显示为红色的叉号)
- Jenkins+Maven+SVN自动部署配置文档
- ThreadPoolExecutor线程的创建与销毁分析
- day01-HTML-后台页面入门
- Spark中的抽象
- 关于Android ContentProdiver 内容提供者的实践体验
- 欢迎使用CSDN-markdown编辑器
- Android——二级列表实现购物车
- 商品管理
- Linux中的tar命令和scp命令
- Intellij IDEA Debug调试技巧