对于线程池线程池就是首先创立一些线程,它们的汇合称为线程池。应用线程池能够很好地进步性能,线程池在系统启动时即创立大量闲暇的线程,程序将一个工作传给线程池,线程池就会启动一条线程来执行这个工作,执行完结当前,该线程并不会死亡,而是再次返回线程池中成为闲暇状态,期待执行下一个工作
为什么要应用线程池多线程运行工夫,零碎一直的启动和敞开新线程,老本十分高,会过渡耗费系统资源,以及过渡切换线程的危险,从而可能导致系统资源的解体。这时,线程池就是最好的抉择了
ThreadPoolExecutor类Java外面线程池的顶级接口是Executor,然而严格意义上讲Executor并不是一个线程池,而只是一个执行线程的工具。真正的线程池接口是ExecutorService
ExecutorService真正的线程池接口。ScheduledExecutorService能和Timer/TimerTask相似,解决那些须要工作反复执行的问题。ThreadPoolExecutorExecutorService的默认实现。ScheduledThreadPoolExecutor继承ThreadPoolExecutor的ScheduledExecutorService接口实现,周期性任务调度的类实现。ThreadPoolExecutor咱们来看一下ThreadPoolExecutor的具体实现:
在ThreadPoolExecutor中有四个构造方法
public class ThreadPoolExecutor extends AbstractExecutorService { /** * Core pool size is the minimum number of workers to keep alive 外围线程数量是维持线程池存活的最小数量,而且不容许超时,除非设置allowCoreThreadTimeOut,在这种状况下最小值为0 * (and not allow to time out etc) unless allowCoreThreadTimeOut * is set, in which case the minimum is zero. */ private volatile int corePoolSize; /** * Maximum pool size. Note that the actual maximum is internally 最大线程数量,留神,理论最大数量受容量限度 * bounded by CAPACITY. */ private volatile int maximumPoolSize; /** * The queue used for holding tasks and handing off to worker 用于保留工作和移交给工作线程 * threads. We do not require that workQueue.poll() returning * null necessarily means that workQueue.isEmpty(), so rely * solely on isEmpty to see if the queue is empty (which we must * do for example when deciding whether to transition from * SHUTDOWN to TIDYING). This accommodates special-purpose * queues such as DelayQueues for which poll() is allowed to * return null even if it may later return non-null when delays * expire. */ private final BlockingQueue<Runnable> workQueue; /** * Timeout in nanoseconds for idle threads waiting for work. 闲暇线程的期待超时工夫,当线程数量超过corePoolSize或者allowCoreThreadTimeOut时应用,否则永远期待新的工作 * 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; /** * Factory for new threads. All threads are created using this 创立线程的工厂 * factory (via method addWorker). All callers must be prepared * for addWorker to fail, which may reflect a system or user's * policy limiting the number of threads. Even though it is not * treated as an error, failure to create threads may result in * new tasks being rejected or existing ones remaining stuck in * the queue. * * We go further and preserve pool invariants even in the face of * errors such as OutOfMemoryError, that might be thrown while * trying to create threads. Such errors are rather common due to * the need to allocate a native stack in Thread.start, and users * will want to perform clean pool shutdown to clean up. There * will likely be enough memory available for the cleanup code to * complete without encountering yet another OutOfMemoryError. */ private volatile ThreadFactory threadFactory; /** * Handler called when saturated or shutdown in execute. 回绝策略,线程饱和或敞开时调用的处理程序 */ private volatile RejectedExecutionHandler handler; //应用指定参数创立线程池,应用默认线程工厂和回绝策略 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) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, defaultHandler); } //应用指定参数创立线程池,应用默认线程工厂 public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, RejectedExecutionHandler handler) { this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, Executors.defaultThreadFactory(), handler); } //应用指定参数创立线程池 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; }}corePoolSize:外围池的大小,这个参数跟前面讲述的线程池的实现原理有十分大的关系。在创立了线程池后,默认状况下,线程池中并没有任何线程,而是期待有工作到来才创立线程去执行工作,除非调用了prestartAllCoreThreads()或者prestartCoreThread()办法,从这2个办法的名字就能够看出,是预创立线程的意思,即在没有工作到来之前就创立corePoolSize个线程或者一个线程。默认状况下,在创立了线程池后,线程池中的线程数为0,当有工作来之后,就会创立一个线程去执行工作,当线程池中的线程数目达到corePoolSize后,就会把达到的工作放到缓存队列当中;maximumPoolSize:线程池最大线程数,这个参数也是一个十分重要的参数,它示意在线程池中最多能创立多少个线程;keepAliveTime:示意线程没有工作执行时最多放弃多久工夫会终止。默认状况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用,直到线程池中的线程数不大于corePoolSize,即当线程池中的线程数大于corePoolSize时,如果一个线程闲暇的工夫达到keepAliveTime,则会终止,直到线程池中的线程数不超过corePoolSize。然而如果调用了allowCoreThreadTimeOut(boolean)办法,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0;unit:参数keepAliveTime的工夫单位workQueue:一个阻塞队列,用来存储期待执行的工作,这个参数的抉择也很重要,会对线程池的运行过程产生重大影响,一般来说,这里的阻塞队列有以下几种抉择
...