线程池能处理业务中多个线程并发的问题,避免大量产生新的线程相互抢占系统资源,可以统一通过线程池来配置不同参数来管理线程。java中已经内置好了四种线程池供我们使用。
线程池创建的参数
corePoolSize 核心线程数 一般情况下一直存活,即使没有任务
maximumPoolSize 最大线程池数量
keepAliveTime 非核心线程的闲置时长 当非核心线程的空闲时间超过该时长,会被回收节省资源,当设置allowCoreThreadTimeOut为true时候,核心线程也会被该规则回收
TimeUnit 指定keepAliveTime的时间单位
BlockingQueue 线程池的任务队列 通过execute(Runnable command)方法将任务放入队列中
ThreadFactory 线程工厂 是一个接口 Thread newThread(Runnable var1)用来创建新的线程
RejectedExecutionHandler 线程池对拒绝任务的处理策略 当线程池满了或者产生其他异常,对未进入线程池的任务进行大的处理策略,可以不用传,有默认值。
JAVA中已经为我们提供了四种参数设置好的线程池
//nThreads 核心线程数
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(4);
//执行任务
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
Log.e("tag","执行任务");
}
});
//关闭线程池
fixedThreadPool.shutdown();
特点:指定一个一定数量的工作线程的线程池,可以节省线程创建的时间提高使用效率,当工作线程达到最大线程数数量,新的任务会进入等待队列。但是当线程池空闲时候,空闲线程也不会销毁,因为创建的只为核心线程。
ScheduledExecutorService scheduledExecutorService =
Executors.newScheduledThreadPool(5);
scheduledExecutorService.schedule(new Runnable() {
@Override
public void run() {
Log.e("tag", "延迟2秒再提交任务");
}
}, 2, TimeUnit.SECONDS);
scheduledExecutorService.scheduleWithFixedDelay(new Runnable() {
@Override
public void run() {
Log.e("tag", "延迟2秒后,每隔1秒执行任务");
}
}, 2, 1, TimeUnit.SECONDS);
scheduledExecutorService.shutdown();
特点:指定一个指定数量的核心线程数,非核心线程数无限制。支持定时延迟执行任务和周期性执行任务。没超过核心线程数情况可减少线程创建时间,超过会新建工作线程,闲置时候会被马上回收。
ExecutorService executorService = Executors.newCachedThreadPool();
executorService.execute(new Runnable() {
@Override
public void run() {
Log.e("执行任务","执行任务");
}
});
executorService.shutdown();
特点:没有核心线程数,非核心线程可无限扩大,使用灵活,空闲线程也会被即时回收。任何线程任务提交是,会被立即执行,无需等待。
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
singleThreadExecutor.execute(new Runnable() {
@Override
public void run() {
Log.e("tag","执行任务");
}
});
singleThreadExecutor.shutdown();
特点:只创建一个唯一的核心线程来工作,所有任务按照(先进先出,后进先出)的规则执行。可解决银行存钱取钱模型问题,同时保证线程安全,数据不会错乱。
几个大库使用的线程池:
创建非核心线程为无限大,实际上受maxRequests(默认值为65)影响。
public synchronized ExecutorService executorService() {
if (executorService == null) {
executorService = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60, TimeUnit.SECONDS,
new SynchronousQueue(), Util.threadFactory("OkHttp Dispatcher", false));
}
return executorService;
}
synchronized void enqueue(AsyncCall call) {
if (runningAsyncCalls.size() < maxRequests && runningCallsForHost(call) < maxRequestsPerHost) {
runningAsyncCalls.add(call);
executorService().execute(call);
} else {
readyAsyncCalls.add(call);
}
}
CachedWorkerPool(long keepAliveTime, TimeUnit unit, ThreadFactory threadFactory) {
this.keepAliveTime = unit != null ? unit.toNanos(keepAliveTime) : 0L;
this.expiringWorkerQueue = new ConcurrentLinkedQueue();
this.allWorkers = new CompositeDisposable();
this.threadFactory = threadFactory;
ScheduledExecutorService evictor = null;
Future> task = null;
if (unit != null) {
evictor = Executors.newScheduledThreadPool(1, EVICTOR_THREAD_FACTORY);
task = evictor.scheduleWithFixedDelay(this, this.keepAliveTime, this.keepAliveTime, TimeUnit.NANOSECONDS);
}
evictorService = evictor;
evictorTask = task;
}
自己简单的封装
public class ThreadPoolManager {
private long keepAliveTime = 10;//存活时间
private TimeUnit unit = TimeUnit.MINUTES;
private final ThreadPoolExecutor mThreadPoolExecutor;
//静态内部类,
private static class HelperSinger{
private static ThreadPoolManager sSingletonTest = new ThreadPoolManager();
}
private ThreadPoolManager(){
int corePoolSize = Runtime.getRuntime().availableProcessors()*2+1;
int maxmunPoolSize = corePoolSize;
//LinkedBlockingQueue 先进先去
//defaultThreadFactory 线程工厂
//AbortPolicy 队列满额的拒绝策略
mThreadPoolExecutor = new ThreadPoolExecutor(corePoolSize, maxmunPoolSize,
keepAliveTime, unit, new LinkedBlockingQueue<>(),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.AbortPolicy());
}
public static ThreadPoolManager getInstace(){
return HelperSinger.sSingletonTest;
}
public void execute(Runnable runnable){
if(runnable==null)return;
mThreadPoolExecutor.execute(runnable);
}
/**
* 从线程池中移除任务
*/
public void remove(Runnable runnable){
if(runnable==null)return;
mThreadPoolExecutor.remove(runnable);
}
public void shutDown(Runnable runnable){
if(mThreadPoolExecutor.isShutdown())return;
mThreadPoolExecutor.shutdown();
}
}
总结:多看其他库的源码(okhttp,rxjava,fresco),里面都有用到线程池,而且用的很深,看不懂。