线程池的状态及KeepAliveTime参数
来源:互联网 发布:golang syscall.exec 编辑:程序博客网 时间:2024/06/05 04:55
原文:https://segmentfault.com/a/1190000004998918
五个状态
// runState is stored in the high-order bits private static final int RUNNING = -1 << COUNT_BITS; private static final int SHUTDOWN = 0 << COUNT_BITS; private static final int STOP = 1 << COUNT_BITS; private static final int TIDYING = 2 << COUNT_BITS; private static final int TERMINATED = 3 << COUNT_BITS;
循环getTask方法
/** * Performs blocking or timed wait for a task, depending on * current configuration settings, or returns null if this worker * must exit because of any of: * 1. There are more than maximumPoolSize workers (due to * a call to setMaximumPoolSize). * 2. The pool is stopped. * 3. The pool is shutdown and the queue is empty. * 4. This worker timed out waiting for a task, and timed-out * workers are subject to termination (that is, * {@code allowCoreThreadTimeOut || workerCount > corePoolSize}) * both before and after the timed wait. * * @return task, or null if the worker must exit, in which case * workerCount is decremented */ 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; //默认allowCoreThreadTimeOut为false,除非程序指定 //(1)当没有超过核心线程时,默认allowCoreThreadTimeOut为false时 //timed值为false,始终break掉,不会销毁线程 //(2)当超过核心线程数,默认allowCoreThreadTimeOut为false时 //timed值为true,如果超过最大值,则销毁;如果timeout过,则销毁 // 如果allowCoreThreadTimeOut为true,则timed始终为true 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; } } }
线程池状态大于SHUTDOWN值的两种情况
1、调用shutdown方法
当线程池调用了shutdown方法,线程池的状态会首先被设置为SHUTDOWN,然后遍历线程池中所有线程,调用一次interrupt方法,如果在休眠中的线程将会激活,激活后的线程以及调用shutdown方法本身的线程都会尝试去调用tryTerminate方法,该方法将判定如果线程池中所有记录的线程数为0,则将线程状态改为TERMINATED,这个值为3,将大于SHUTDOWN状态值。
2、调用shutdownNow方法
当线程调用了shutdownNow方法后,首先将线程的状态修改为STOP,这个状态是大于SHUTDOWN值的,接下来它也会通过中断激活线程,只是它来的更暴力一些,连加锁和一些基本判断都没有,直接中断;在调用tryTerminate之前会先清空阻塞队列中所有的元素,这些元素被组装为一个List列表作为shutdownNow方法的返回值。换句话说,没有执行的任务在shutdownNow执行后的返回值中可以得到。在程序某些必要的情况下,可以通过线程池的isTerminating,isTerminated,isStopped,isShutdown来对线程做一些状态判定。
KeepAliveTime参数
workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS)
当阻塞队列中没有任务时,等待时间达到keepAliveTime毫秒值时就会被自动唤醒,而不会永远地沉睡下去。
keepAliveTime,如果是通过newCachedThreadPool的话,默认是1分钟超时,如果遇到前面所提到的瞬间冲击,那么线程池数量将瞬间快速膨胀,而且这些瞬间膨胀的线程的生命周期最少在1分钟以上。
如果设置了该参数,那么当timeout的时候,就return null,就会跳出循环,回收线程。
if (wc <= maximumPoolSize && ! (timedOut && timed)) break; if (compareAndDecrementWorkerCount(c)) return null;
allowCoreThreadTimeout : 默认情况下核心线程不会退出,可通过将该参数设置为true,让核心线程也退出。
默认的Executors工厂,只有newCachedThreadPool,timeout为60秒,出现timeout情况下,而且线程数超过了核心线程数,会销毁销毁线程。保持在corePoolSize数(如果是cached的,corePoolSize为0)。
/** * Timeout in nanoseconds for idle threads waiting for work. * Threads use this timeout when there are more than corePoolSize * present or if allowCoreThreadTimeOut. Otherwise they wait * forever for new work. */ private volatile long keepAliveTime; /** * If false (default), core threads stay alive even when idle. * If true, core threads use keepAliveTime to time out waiting * for work. */ private volatile boolean allowCoreThreadTimeOut;
线程池最小是corePoolSize,最大是maximumPoolSize,除非设置了allowCoreThreadTimeOut和超时时间,这种情况线程数可能减少到0,最大可能是Integer.MAX_VALUE。
Core pool size is the minimum number of workers to keep alive(and not allow to time out etc) unless allowCoreThreadTimeOut is set, in which case the minimum is zero.
/** * Creates a thread pool that creates new threads as needed, but * will reuse previously constructed threads when they are * available. These pools will typically improve the performance * of programs that execute many short-lived asynchronous tasks. * Calls to <tt>execute</tt> will reuse previously constructed * threads if available. If no existing thread is available, a new * thread will be created and added to the pool. Threads that have * not been used for sixty seconds are terminated and removed from * the cache. Thus, a pool that remains idle for long enough will * not consume any resources. Note that pools with similar * properties but different details (for example, timeout parameters) * may be created using {@link ThreadPoolExecutor} constructors. * * @return the newly created thread pool */ public static ExecutorService newCachedThreadPool() { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>()); } /** * Creates a thread pool that creates new threads as needed, but * will reuse previously constructed threads when they are * available, and uses the provided * ThreadFactory to create new threads when needed. * @param threadFactory the factory to use when creating new threads * @return the newly created thread pool * @throws NullPointerException if threadFactory is null */ public static ExecutorService newCachedThreadPool(ThreadFactory threadFactory) { return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), threadFactory); }
超时timeout设置为0的话,表示不等待
public E poll(long timeout, TimeUnit unit) throws InterruptedException { return pollFirst(timeout, unit); }
具体如下
public E pollFirst(long timeout, TimeUnit unit) throws InterruptedException { long nanos = unit.toNanos(timeout); final ReentrantLock lock = this.lock; lock.lockInterruptibly(); try { E x; while ( (x = unlinkFirst()) == null) { if (nanos <= 0) return null; nanos = notEmpty.awaitNanos(nanos); } return x; } finally { lock.unlock(); } }
- 线程池的状态及KeepAliveTime参数
- java 线程池keepAliveTime含义
- 线程池之状态参数
- 线程的状态及通信
- 线程的定义及状态
- 线程的基本概念及状态
- 线程的状态及转化
- 线程的生命周期及状态的管理
- java线程的状态及操作方法
- 线程的状态、分类及优先级
- linux 线程的状态及资源回收
- 线程的生命周期及状态转换
- 线程的生命周期及状态转换
- 进程和线程的状态及转换
- 线程池及线程带参数
- explain各个参数的状态及含义
- Java线程的5种状态及状态之间转换
- 线程的状态、调度及线程的同步与锁
- Ubuntu安装sendmail失败卡死问题解决方案
- 解决cookie中文乱码问题
- 2017.12.07 定时任务
- 10034---mysql更新记录时设置自动更新时间戳
- oracle11G EM ORA-28001: the password has expired (DBD ERROR: OCISessionBegin)
- 线程池的状态及KeepAliveTime参数
- CSS书写规范、顺序
- PHP软件编码规范
- CentOS7 64位下MySQL5.7安装与配置(YUM)
- python图片合成
- liunx的基础命令-03
- 四轴飞行器姿态解算必不可少的知识点
- Chrome 下载crx
- Linux上的free命令详解(讲解最清楚最靠谱的)