http://blog.csdn.net/wangpeng047/article/details/7748457
一、线程池的作用
线程池作用就是限制系统中执行线程的数量。
根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果;如果线程少了会浪费系统资源,多了又会造成系统拥挤效率不高。用线程池控制线程数量,使得其他线程排队等候。一个任务执行完毕,再从队列的中取最前面的任务开始执行。若队列中没有任务等待进程,则线程池中的线程处于等待。
二、为什么要用线程池
减少了创建和销毁线程的次数,每个工作线程都可以被重复利用,可执行多个任务。也可以根据系统的承受能力,调整线程池中工作线线程的数目,防止因为消耗过多的内存,而把服务器累趴下(每个线程需要大约1MB内存,线程开的越多,消耗的内存也就越大,最后死机)。
三、线程池的原理
其实线程池的原理很简单,类似于操作系统中的缓冲区的概念,它的流程如下:先启动若干数量的线程,并让这些线程都处于睡眠状态,当客户端有一个新请求时,就会唤醒线程池中的某一个睡眠线程,让它来处理客户端的这个请求,当处理完这个请求后,线程又处于睡眠状态。
四、java线程池
java关于线程池的主要内容有:
接口:Executor、ExecutorService、ScheduledExecutorService、CompletionService
类:Executors、AbstractExecutorService、ThreadPoolExecutor、ScheduledThreadPoolExecutor、ExecutorCompletionService
以上这些,我不可能一一介绍,这里只介绍重要的两个类Executors和ThreadPoolExecutor
1. ThreadPoolExecutor
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory,
RejectedExecutionHandler handler)
参数:
● corePoolSize - 池中所保存的线程数,包括空闲线程。
● maximumPoolSize - 池中允许的最大线程数。
● keepAliveTime - 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
● unit - keepAliveTime 参数的时间单位。
● workQueue - 执行前用于保持任务的队列。此队列仅保持由 execute 方法提交的 Runnable 任务。
● threadFactory - 执行程序创建新线程时使用的工厂。
● handler - 由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序。
抛出:
● IllegalArgumentException - 如果 corePoolSize 或 keepAliveTime 小于 0,或者 maximumPoolSize 小于等于 0,或者 corePoolSize 大于 maximumPoolSize。
● NullPointerException - 如果 workQueue、threadFactory 或 handler 为 null。
● unit可选的参数为java.util.concurrent.TimeUnit中的几个静态属性:
NANOSECONDS、MICROSECONDS、MILLISECONDS、SECONDS
● workQueue我常用的是:java.util.concurrent.ArrayBlockingQueue
● handler有四个选择:
1. ThreadPoolExecutor.AbortPolicy()
抛出java.util.concurrent.RejectedExecutionException异常
2. ThreadPoolExecutor.CallerRunsPolicy()
重试添加当前的任务,他会自动重复调用execute()方法
3. ThreadPoolExecutor.DiscardOldestPolicy()
抛弃旧的任务
4. ThreadPoolExecutor.DiscardPolicy()
抛弃当前的任务
一个任务通过execute(Runnable)方法被添加到线程池,任务就是一个 Runnable类型的对象,任务的执行方法就是 Runnable类型对象的run()方法。
当一个任务通过execute(Runnable)方法欲添加到线程池时,会有以下:
1. 如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。
2. 如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。
3. 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maximumPoolSize,建新的线程来处理被添加的任务。
4. 如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maximumPoolSize,那么通过 handler所指定的策略来处理此任务。也就是处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。
5. 当线程池中的线程数量大于 corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。