为啥非得要线程池,new Thread().start()。用的如此的爽
1.线程池的选择主要是线程的复用,减少线程的创建和销毁带来的开销;
2.控制线程的并发数,当大量线程争夺cpu资源的时候容易造成阻塞;
3.当然线程池能更好管理这些脱缰的线程们;
无论什么样的线程,最终肯定跑不掉老祖宗ThreadPoolExecutor,先认识一下
public ThreadPoolExecutor(
//核心线程数,除非allowCoreThreadTimeOut被设置为true,否则它闲着也不会死
int corePoolSize,
//最大线程数,活动线程数量超过它,后续任务就会排队
int maximumPoolSize,
//超时时长,作用于非核心线程(allowCoreThreadTimeOut被设置为true时也会同时作用于核心线程),闲置超时便被回收
long keepAliveTime,
//枚举类型,设置keepAliveTime的单位,有TimeUnit.MILLISECONDS(ms)、TimeUnit. SECONDS(s)等
TimeUnit unit,
//缓冲任务队列,线程池的execute方法会将Runnable对象存储起来
BlockingQueue<Runnable> workQueue,
//线程工厂接口,只有一个new Thread(Runnable r)方法,可为线程池创建新线程
ThreadFactory threadFactory)
最主要的就是核心线程数了,讨论一下核心线程和当前任务数量(currentSize)的效果
1.当currentSize<corePoolSize时,没什么好说的,直接启动一个核心线程并执行任务;
2.当currentSize>=corePoolSize、并且workQueue未满时,添加进来的任务会被安排到workQueue中等待执行;
3.当workQueue已满,但是currentSize<maximumPoolSize时,会立即开启一个非核心线程来执行任务。
4.当currentSize>=corePoolSize、workQueue已满、并且currentSize>maximumPoolSize时,调用handler默认抛出RejectExecutionExpection异常。
workQueue未满只会用核心线程,等待也无妨,满了就需要找帮手非核心线程来处理,就是这么犟
到了新一代的实战型线程池了
Android中最常见的四类具有不同特性的线程池分别为:
FixThreadPool(固定大小线程池)
SingleThreadExecutor(单个线程池)
CachedThreadPool(缓存线程池)
ScheduleThreadPool(定时线程池)
1.大公子FixThreadPool
public static ExecutorService newFixThreadPool(int nThreads){
return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
}
//使用
Executors.newFixThreadPool(5).execute(r);
1.看的出来其核心线程数和最大线程数是相等的,也就是只有核心线程,数量固定可传。因为都是核心线程所有线程都是活跃的,因为队列没有限制大小,所以新任务会等待;
2.一堆任务抢占资源,可以有无数个排队,能使用资源的就nThreads个。就是任务都执行完毕了,也不会销毁;
3.由于都是核心线程,FixThreadPool能快速响应外界请求。
2.二公子SingleThreadPool
public static ExecutorService newSingleThreadPool (){
return new FinalizableDelegatedExecutorService ( new ThreadPoolExecutor (1, 1, 0, TimeUnit. MILLISECONDS, new LinkedBlockingQueue<Runnable>()) );
}
//使用
Executors.newSingleThreadPool ().execute(r);
1.只有一个核心线程,而且只允许有一个线程,确保所有的任务都在同一个线程顺序完成,不需要处理同步问题;
3.三公子CachedThreadPool
public static ExecutorService newCachedThreadPool(int nThreads){
return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit. SECONDS, new SynchronousQueue<Runnable>());
}
//使用
Executors.newCachedThreadPool().execute(r);
1.CachedThreadPool只有非核心线程,最大线程非常大,所有线程都活动时,会为新任务创建新的线程,否则复用空闲的线程,有60s的空闲时间,过了就会被系统回收,所以存在0线程的可能;
2.适合大量耗时较少的任务。
3.四公子ScheduledThreadPool
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize){
return new ScheduledThreadPoolExecutor(corePoolSize);
}
public ScheduledThreadPoolExecutor(int corePoolSize){
super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedQueue ());
}
//使用,延迟1秒执行,每隔2秒执行一次Runnable r
Executors. newScheduledThreadPool (5).scheduleAtFixedRate(r, 1000, 2000, TimeUnit.MILLISECONDS);
1.核心线程数量固定,非核心线程数量巨大;
2.执行定时任务以及有固定周期的重复任务。