提到线程池每一个开发者都知道其中的好处,我们不得不提线程池的好处:
1.重用线程池中线程,避免因为线程的初始化和销毁带来的性能开销
2.能有限控制线程池中的最大并发数,避免因为线程间互相抢占系统资源而导致的阻塞
3.能有效的并且简单的线程管理,并提供简单和建个轮询执行等功能
一提到线程池我们肯定需要用到的是ThreadPoolExecutor类:
public ThreadPoolExecutor(int corePoolSize,
int maximumPoolSize,
long keepAliveTime,
TimeUnit unit,
BlockingQueue<Runnable> workQueue,
ThreadFactory threadFactory) {
}
其中的参数分别代表的意思
corePoolSize:线程池中的核心线程数
maximumPoolSize:线程池中最大的线程数量,当活动线程达到这个数量后续加入的线程将被阻塞
keepAliveTime:非核心线程闲置的超时时间,超过这个时长,非核心线程将被回收
unit:对应的是keepAliveTime的时长单位
workQueue:线程池中任务队列,通过execute方法提交的Runnable将被存储到这个queue中
threadFactory:线程工厂,提供统一初始化线程的入口
知道这些参数意思之后那么重点来了 如何创建一个高效的线程池呢,直接把代码附上
/**
* CPU核心数
*/
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
/**
* 核心线程数
*/
private static final int CORE_POOL_SIZE = CPU_COUNT + 1;
/**
* 最大线程数量
*/
private static final int MAXMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
/**
* 非核心线程闲置时间为1秒
*/
private static final int KEEP_TIME = 1;
/**
* 线程工厂类
*/
private static final ThreadFactory mThreadFactory = new ThreadFactory() {
private final AtomicInteger mCount = new AtomicInteger(1);
@Override
public Thread newThread(Runnable r) {
return new Thread(r, "Thread Current ID = " + mCount.getAndIncrement());
}
};
/**
* 线程池任务队列容量为128
*/
private static final BlockingQueue<Runnable> mPoolWorkQueue = new LinkedBlockingQueue<>(128);
/**
* 线程池
*/
private static final ThreadPoolExecutor mThreadPoolExecutor = new ThreadPoolExecutor(
CORE_POOL_SIZE, MAXMUM_POOL_SIZE, KEEP_TIME, TimeUnit.SECONDS, mPoolWorkQueue, mThreadFactory);
通过代码注释可以一览无余每一个参数的意思了。
不过我们需要总结一下ThreadPoolExecutor的执行任务准则:
1.如果线程池中的线程数量未达到核心线程数,那么会直接启动一个新线程类执行任务
2.如果核心线程数量已满,那么新增的会被插入任务队列中等待核心线程完成才执行
3.如果任务队列已经满了但是未达到线程的最大值,那么会启动一个非核心线程来执行任务
4.如何线程已经达到了最大的线程数时,那么会拒绝执行此任务会执行rejectedExecution方法回调给调用者
最后,在需要的地方执行如下方法即可把把线程加入线程池中执行:
Runnable mRunnable = new Runnable() {
@Override
public void run() {
// do someThing...
}
};
mThreadPoolExecutor.execute(mRunnable);