赞
踩
创建一个可根据需要创建新线程的线程池,但是在以前构造的线程可用时将重用它们。对于执行
很多短期异步任务的程序而言,这些线程池通常可提高程序性能。
创建一个可重用固定线程数的线程池,以共享的无界队列方式来运行这些线程。
创建一个线程池,它可安排在给定延迟后运行命令或者定期地执行。
ThreadPoolExecutor与前几个线程池对比要更灵活
创建一个新的线程可以通过继承Thread类或者实现Runnable接口来实现,这两种方式创建的线程在运行结束后会被虚拟机销毁,进行垃圾回收,如果线程数量过多,频繁的创建和销毁线程会浪费资源,降低效率。而线程池的引入就很好解决了上述问题,线程池可以更好的创建、维护、管理线程的生命周期,做到复用,提高资源的使用效率,也避免了开发人员滥用new关键字创建线程的不规范行为。
ThreadPoolExecutor数据结构有 HashSet、BlockingQueue、Worker、AbstractQueuedSynchronizer构成。
1、任务添加 - 当线程池任务数小于核心线程数时,Worker 是继承Runnable的包装类,每一个任务都使用Worker包装起来,然后将包装对象存入HashSet中,直接唤醒其线程执行。
2、任务添加 - 当线程池任务数大于核心线程数时,执行方法直接放入BlockingQueue队列中,排队执行。如果队列满了执行队列拒绝策略。
3、线程回收- 当执行线程大于核心线程 或者 线程池关闭 或者 核心线程keepAliveTimeOut超时时候触发interruptIdleWorkers方法。 注意点interruptIdleWorkers回收原则是线程是否被发出中断请求,如果被发出中断请求执行回收。
属性名称 | 解释 | 功能描述 |
---|---|---|
keepAliveTime | 线程空闲时间 | 一个线程处在空闲状态的时间超过了该属性值,就会因为超时而退出。举个例子,如果线程池的核心大小corePoolSize=5,而当前大小poolSize =8,那么超出核心大小的线程,会按照keepAliveTime的值判断是否会超时退出。如果线程池的核心大小corePoolSize=5,而当前大小poolSize =5,那么线程池中所有线程都是核心线程,这个时候线程是否会退出,取决于allowCoreThreadTimeOut |
allowCoreThreadTimeOut | 核心线程超时关闭 | 该属性用来控制是否允许核心线程超时退出。默认值为:false。如果线程池的大小已经达到了corePoolSize,不管有没有任务需要执行,线程池都会保证这些核心线程处于存活状态。该属性只是用来控制核心线程的 |
poolSize | 线程池中当前线程的数量 | 线程池中当前线程的数量,当该值为0的时候,意味着没有任何线程 |
corePoolSize | 核心线程数 | 线程池的基本大小,即在没有任务需要执行的时候线程池的大小,并且只有在工作队列满了的情况下才会创建超出这个数量的线程。这里需要注意的是:在刚刚创建ThreadPoolExecutor的时候,线程并不会立即启动,而是要等到有任务提交时才会启动,除非调用了prestartCoreThread/prestartAllCoreThreads事先启动核心线程。再考虑到keepAliveTime和allowCoreThreadTimeOut超时参数的影响,所以没有任务需要执行的时候,线程池的大小不一定是corePoolSize |
maximumPoolSize | 线程池中允许的最大线程数 | 线程池中允许的最大线程数,线程池中的当前线程数目不会超过该值。如果队列中任务已满,并且当前线程个数小于maximumPoolSize,那么会创建新的线程来执行任务。这里值得一提的是largestPoolSize,该变量记录了线程池在整个生命周期中曾经出现的最大线程个数。为什么说是曾经呢?因为线程池创建之后,可以调用setMaximumPoolSize()改变运行的最大线程的数目 |
queueCapacity | 任务队列容量(阻塞队列 | 当核心线程数达到最大时,新任务会放在队列中排队等待执行 |
rejectedExecutionHandler | 任务拒绝处理器 | * 两种情况会拒绝处理任务: - 当线程数已经达到maxPoolSize,切队列已满,会拒绝新任务 - 当线程池被调用shutdown()后,会等待线程池里的任务执行完毕,再shutdown。如果在调用shutdown()和线程池真正shutdown之间提交任务,会拒绝新任务 * 线程池会调用rejectedExecutionHandler来处理这个任务。如果没有设置默认是AbortPolicy,会抛出异常 * ThreadPoolExecutor类有几个内部实现类来处理这类情况: - AbortPolicy 丢弃任务,抛运行时异常 - CallerRunsPolicy 执行任务 - DiscardPolicy 忽视,什么都不会发生 - DiscardOldestPolicy 从队列中踢出最先进入队列(最后一个执行)的任务 * 实现RejectedExecutionHandler接口,可自定义处理器 |
1、当前线程数小于核心线程数,addWoker直接添加入Hashset中,直接唤醒addWorker线程执行。
- public void execute(Runnable command) {
- if (command == null)
- throw new NullPointerException();
- int c = ctl.get();
-
- //线程小于核心线程数,addWorker添加Hashset直接唤醒线程执行
- 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);
- }

线程池队列线程执行情况
- 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 ((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);
- }
- }

线程回收方法是线程安全的,如果线程被中断执行回收。
- //线程池线程回收
- private void interruptIdleWorkers(boolean onlyOne) {
- final ReentrantLock mainLock = this.mainLock;
- mainLock.lock();
- try {
- for (Worker w : workers) {
- Thread t = w.thread;
- if (!t.isInterrupted() && w.tryLock()) {
- try {
- t.interrupt();
- } catch (SecurityException ignore) {
- } finally {
- w.unlock();
- }
- }
- if (onlyOne)
- break;
- }
- } finally {
- mainLock.unlock();
- }
- }

Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。