线程池的构造方法
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue) {
this(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue,
Executors.defaultThreadFactory(), defaultHandler);
}
参数的意义:
-
corePoolSize:核心池的大小,在创建了线程池后,默认情况下,线程池中并没有任何线程,而是等待有任务到来才创建线程去执行任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中。只有当工作队列满了的情况下才会创建超出这个数量的线程。如果某个线程的空闲时间超过了活动时间,那么将标记为可回收,并且只有当线程池的当前大小超过corePoolSize时该线程才会被终止。用户可调用prestartAllCoreThreads()或者prestartCoreThread()方法预先创建线程,即在没有任务到来之前就创建corePoolSize个线程或者一个线程。
-
maximumPoolSize:线程池最大线程数,这个参数也是一个非常重要的参数,它表示在线程池中最多能创建多少个线程;当大于了这个值就会将Thread由一个丢弃处理机制来处理。
-
keepAliveTime:表示线程没有任务执行时最多保持多久时间会终止。默认情况下,只有当线程池中的线程数大于corePoolSize时,keepAliveTime才会起作用,直到线程池中的线程数不大于corePoolSize,即当线程池中的线程数大于corePoolSize时,如果一个线程空闲的时间达到keepAliveTime,则会终止,直到线程池中的线程数不超过corePoolSize。但是如果调用了allowCoreThreadTimeOut(boolean)方法,在线程池中的线程数不大于corePoolSize时,keepAliveTime参数也会起作用,直到线程池中的线程数为0;
-
Unit:参数keepAliveTime的时间单位,有7种取值,在TimeUnit类中有7种静态属性。
-
workQueue:一个阻塞队列,用来存储等待执行的任务,当线程池中的线程数目达到corePoolSize后,就会把到达的任务放到缓存队列当中。
-
threadFactory:线程工厂,主要用来创建线程;
-
handler:表示当拒绝处理任务时的策略,也就是参数maximumPoolSize达到后丢弃处理的方法。有以下四种取值:
ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
ThreadPoolExecutor.CallerRunsPolicy:由调用线程处理该任务
用户也可以实现接口RejectedExecutionHandler定制自己的策略。
线程池Demo
1、工厂方法:
public class ThreadPoolProxyFactory {
static ThreadPoolProxy mNormalThreadPoolProxy;
static ThreadPoolProxy mDownLoadThreadPoolProxy;
/**
* 得到普通线程池代理对象mNormalThreadPoolProxy
*/
public static ThreadPoolProxy getNormalThreadPoolProxy() {
if (mNormalThreadPoolProxy == null) {
synchronized (ThreadPoolProxyFactory.class) {
if (mNormalThreadPoolProxy == null) {
mNormalThreadPoolProxy = new ThreadPoolProxy(5, 5);
}
}
}
return mNormalThreadPoolProxy;
}
/**
* 得到下载线程池代理对象mDownLoadThreadPoolProxy
*/
public static ThreadPoolProxy getDownLoadThreadPoolProxy() {
if (mDownLoadThreadPoolProxy == null) {
synchronized (ThreadPoolProxyFactory.class) {
if (mDownLoadThreadPoolProxy == null) {
mDownLoadThreadPoolProxy = new ThreadPoolProxy(3, 3);
}
}
}
return mDownLoadThreadPoolProxy;
}
}
2、线程池代理
public class ThreadPoolProxy {
ThreadPoolExecutor mExecutor;
private int mCorePoolSize;
private int mMaximumPoolSize;
/**
* @param corePoolSize 核心池的大小
* @param maximumPoolSize 最大线程数
*/
public ThreadPoolProxy(int corePoolSize, int maximumPoolSize) {
mCorePoolSize = corePoolSize;
mMaximumPoolSize = maximumPoolSize;
}
/**
* 初始化ThreadPoolExecutor
* 双重检查加锁,只有在第一次实例化的时候才启用同步机制,提高了性能
*/
private void initThreadPoolExecutor() {
if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()) {
synchronized (ThreadPoolProxy.class) {
if (mExecutor == null || mExecutor.isShutdown() || mExecutor.isTerminated()) {
long keepAliveTime = 3000;
TimeUnit unit = TimeUnit.MILLISECONDS;
BlockingQueue workQueue = new LinkedBlockingDeque<>();
ThreadFactory threadFactory = Executors.defaultThreadFactory();
RejectedExecutionHandler handler = new ThreadPoolExecutor.DiscardPolicy();
mExecutor = new ThreadPoolExecutor(mCorePoolSize, mMaximumPoolSize, keepAliveTime, unit, workQueue,
threadFactory, handler);
}
}
}
}
/**
执行任务和提交任务的区别?
1.有无返回值
execute->没有返回值
submit-->有返回值
2.Future的具体作用?
1.有方法可以接收一个任务执行完成之后的结果,其实就是get方法,get方法是一个阻塞方法
2.get方法的签名抛出了异常===>可以处理任务执行过程中可能遇到的异常
*/
/**
* 执行任务
*/
public void execute(Runnable task) {
initThreadPoolExecutor();
mExecutor.execute(task);
}
/**
* 提交任务
*/
public Future submit(Runnable task) {
initThreadPoolExecutor();
return mExecutor.submit(task);
}
/**
* 移除任务
*/
public void remove(Runnable task) {
initThreadPoolExecutor();
mExecutor.remove(task);
}
}
3、线程池使用(具体runnable自己定义,线程的参数自己灵活修改):
ThreadPoolProxyFactory .getNormalThreadPoolProxy().execute(Runnable);