线程池组成
一个线程池包括以下四个基本组成部分:
1、线程池管理器(ThreadPool):用于创建并管理线程池,包括 创建线程池,销毁线程池,添加新任务;
2、工作线程(PoolWorker):线程池中线程,在没有任务时处于等待状态,可以循环的执行任务;
3、任务接口(Task):每个任务必须实现的接口,以供工作线程调度任务的执行,它主要规定了任务的入口,任务执行完后的收尾工作,任务的执行状态等;
4、任务队列(taskQueue):用于存放没有处理的任务。提供一种缓冲机制。
线程池种类
创建一个单线程的线程池,以无界队列方式运行。这个线程池只有一个线程在工作(如果这个唯一的线程因为异常结束,那么会有一个新的线程来替代它。)此线程池能够保证所有任务的执行顺序按照任务的提交顺序执行,同一时段只有一个任务在运行。
此类型线程池特别适合于需要保证执行顺序的场合。
2、newFixedThreadPool
创建固定大小的线程池,以无界队列方式运行。线程池满且线程都为活动状态的时候如果有新任务提交进来,它们会等待直到有线程可用。线程池的大小一旦达到最大值就会保持不变,如果某个线程因为执行异常而结束,那么线程池会补充一个新线程。显式调用shutdown将关闭线程池。
此类型线程池比较符合常用场合。
3、newCachedThreadPool
创建一个可缓存的线程池。必要的时候创建新线程来处理请求,也会重用线程池中已经处于可用状态的线程。如果线程池的大小超过了处理任务所需要的线程,那么就会回收部分空闲(60秒不执行任务)的线程;当任务数增加时,此线程池又可以智能的添加新线程来处理任务。此线程池不会对线程池大小做限制,线程池大小完全依赖于操作系统(或者说JVM)能够创建的最大线程大小。
此类型线程池特别适合于耗时短,不需要考虑同步的场合。
4、newScheduledThreadPool创建可定时运行(初始延时),运行频率(每隔多长时间运行,还是运行成功一次之后再隔多长时间再运行)的线程池。
此类型线程池适合定时以及周期性执行任务的场合。
线程池的jdk实现corePoolSize的作用
在生成的线程池ThreadPoolExecutor中,有一个corePoolSize属性,它的作用是用来判断是否要创建新的线程,如果当前线程池中线程的数量大于corePoolSize,则有空闲线程则使用,没有空闲线程则创建线程。如果小于corePoolSize则不管怎样,都会从新创建线程。
/**
* Core pool size, updated only while holding mainLock, but
* volatile to allow concurrent readability even during updates.
*/
private volatile int corePoolSize;
执行线程池的execute方法时,不同的线程池种类不同的响应
public void execute(Runnable command) {
if (command == null)
throw new NullPointerException();
if (poolSize >= corePoolSize || !addIfUnderCorePoolSize(command)) {
if (runState == RUNNING && workQueue.offer(command)) {
if (runState != RUNNING || poolSize == 0)
ensureQueuedTaskHandled(command);
}
else if (!addIfUnderMaximumPoolSize(command))
reject(command); // is shutdown or saturated
}
}
工作线程Worker
工作线程执行它的run方法后,会一直试图去等待队列里面取出任务
/**
* Main run loop
*/
public void run() {
try {
hasRun = true;
Runnable task = firstTask;
firstTask = null;
while (task != null || (task = getTask()) != null) { //注意getTask()方法,它会循环着去取出来任务
runTask(task);
task = null;
}
} finally {
workerDone(this);
}
}它会循环去取出来任务,
Runnable getTask() {
for (;;) {
try {
int state = runState;
if (state > SHUTDOWN)
return null;
Runnable r;
if (state == SHUTDOWN) // Help drain queue
r = workQueue.poll();
else if (poolSize > corePoolSize || allowCoreThreadTimeOut)
r = workQueue.poll(keepAliveTime, TimeUnit.NANOSECONDS);
else
r = workQueue.take(); //注意这一句话,对于固定大小的线程池和可缓冲的线程池,使用的队列类型不一样,一个时阻塞队列,一个是同步队列
if (r != null)
return r;
if (workerCanExit()) { // 获取不到任务时,对于可缓冲队列有一个退出机制
if (runState >= SHUTDOWN) // Wake up others
interruptIdleWorkers();
return null;
}
// Else retry
} catch (InterruptedException ie) {
// On interruption, re-check runState
}
}
}
原文地址:http://blog.csdn.net/yaoqinggg/article/details/41804859