Android 下的线程池
- FixedThreadPool
是一种线程数量固定的线程池,当线程处于空闲状态时,不会被回收,除非线程池关闭了,当所有的线程处于活动状态时,新任务处于等待状态,直到有新的线程空闲出来,由于这个线程池只有核心线程,并且核心线程不会别回收,以为它可以快速响应外界的请求
无超时机制,无任务限制
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(2);
for (int i = 0; i < 20; i++) {
fixedThreadPool.execute(new Runnable() {
@Override
public void run() {
try {
System.out.println(Thread.currentThread().getName() + " :开始执行");
Thread.sleep(5 * 1000);
System.out.println(Thread.currentThread().getName() + " :结束执行");
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
执行结果
pool-1-thread-1 :开始执行
pool-1-thread-2 :开始执行
pool-1-thread-2 :结束执行
pool-1-thread-1 :结束执行
pool-1-thread-2 :开始执行
pool-1-thread-1 :开始执行
pool-1-thread-1 :结束执行
pool-1-thread-2 :结束执行
pool-1-thread-2 :开始执行
pool-1-thread-1 :开始执行
...
- CachedThreadPool
线程数量不固定,只有非核心线程,且最大值为Integer.MAX_VALUE,当线程池中的线程都处于活动状态时,新任务绘开启新的线程处理,负责绘利用空闲的线程处理,线程池中空闲的线程都有超时机制,超时时间为60s,超时绘被自动回收
适合执行大量耗时较少的任务,当整个线程池都处于空闲状态时,线程池中的线程都会因超时而停止,不占系统资源
- ScheduledThreadPool
核心线程数量是固定的,非核心线程数量是没有限制的,非核心线程空闲时绘被回收,
主要用于执行定时任务和固定周期的重复任务
- SingleThreadPool
只有一个核心线程,确保所有的任务都在一个线程中顺序执行,所有的任务都在一个线程中,不需要处理线程同步的问题
线程名称|特点|适用场景|描述
---|:--:|:--:|:--:|---
FixedThreadPool|线程数量固定且只有核心线程,处于空闲状态也不会被回收|可以快速响应外界请求|FixThreadPool其实就像一堆人排队上公厕一样,可以无数多人排队,但是厕所位置就那么多,而且没人上时,厕所也不会被拆迁
CachedThreadPool|线程数量不固定,可以理解为无限,有新新任务就开启线程,超时60s,超时自动回收|适合执行大量耗时较少的任务|CachedThreadPool就像是一堆人去一个很大的咖啡馆喝咖啡,里面服务员也很多,随时去,随时都可以喝到咖啡。但是为了响应国家的“光盘行动”,一个人喝剩下的咖啡会被保留60秒,供新来的客人使用,哈哈哈哈哈,好恶心啊。如果你运气好,没有剩下的咖啡,你会得到一杯新咖啡。但是以前客人剩下的咖啡超过60秒,就变质了,会被服务员回收掉。
ScheduledThreadPool|核心线程数量固定,非核心线程数量没有限制,空闲时会被回收|用于执行定时任务或周期新重复的任务|就像华为公司,里面有若干核心员工,有若干外包公司的员工,在任务忙的时候,核心人员先忙,忙不过来,外包员工上,如果活干完了,外包员工就
SingleThreadPool|只有一个核心线程,所有的任务都在一个线程中执行,不需要处理线程同步的问题|适合执行不需要线程同步的任务|可以把SingleThreadPool简单的理解为FixThreadPool的参数被手动设置为1的情况,即Executors.newFixThreadPool(1).execute(r)。所以SingleThreadPool可以理解为公厕里只有一个坑位,先来先上,后来排队
线程池工具类:
/**
* 线程池代理类
* @author sun
*/
public class ThreadPoolProxy {
private static final String TAG = ThreadPoolProxy.class.getCanonicalName();
private static Serializable serializable;
private ThreadPoolExecutor mThreadPoolExecutor;
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
private static final int MAXIMUM_POOL_SIZE = CPU_COUNT * 2 + 1;
private static final int KEEP_ALIVE_SECONDS = 30;
private static ThreadPoolProxy threadPoolProxy;
private ThreadPoolProxy() {
}
public static ThreadPoolProxy getInstance(Serializable serializable) {
ThreadPoolProxy.serializable = serializable;
if (threadPoolProxy == null) {
synchronized (ThreadPoolProxy.class) {
if (threadPoolProxy == null) {
threadPoolProxy = new ThreadPoolProxy();
}
}
}
return threadPoolProxy;
}
private ThreadPoolExecutor initExecutor() {
if (mThreadPoolExecutor == null) {
synchronized (ThreadPoolProxy.class) {
if (mThreadPoolExecutor == null) {
TimeUnit unit = TimeUnit.MILLISECONDS;
ThreadFactory threadFactory = Executors.defaultThreadFactory();
RejectedExecutionHandler handler = new ThreadPoolExecutor.AbortPolicy();
LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<>();
mThreadPoolExecutor = new ThreadPoolExecutor(
//核心线程数
CORE_POOL_SIZE,
//最大线程数
MAXIMUM_POOL_SIZE,
//保持时间
KEEP_ALIVE_SECONDS,
//保持时间对应的单位
unit,
workQueue,
//线程工厂
threadFactory,
//异常捕获器
handler);
}
}
}
MyLog.d(TAG,"CORE_POOL_SIZE : " + CORE_POOL_SIZE + " MAXIMUM_POOL_SIZE: " + MAXIMUM_POOL_SIZE + " KEEP_ALIVE_SECONDS: " + KEEP_ALIVE_SECONDS);
return mThreadPoolExecutor;
}
/**
* 执行任务
*/
public void executeTask(Runnable r) {
initExecutor();
mThreadPoolExecutor.execute(r);
}
/**
* 提交任务
*/
public Future<?> commitTask(Runnable r) {
initExecutor();
return mThreadPoolExecutor.submit(r);
}
/**
* 删除任务
*/
public void removeTask(Runnable r) {
initExecutor();
mThreadPoolExecutor.remove(r);
}
public Serializable getSerializable(){
return serializable;
}
}
...
定时器工具类
public class TimerUtils {
private static volatile TimerUtils mInstance;
private final ScheduledThreadPoolExecutor executor;
private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
private static final int CORE_POOL_SIZE = Math.max(2, Math.min(CPU_COUNT - 1, 4));
private TimerUtils() {
BasicThreadFactory threadFactory = new BasicThreadFactory.Builder().namingPattern("TimerUtils").daemon(true).build();
executor = new ScheduledThreadPoolExecutor(CORE_POOL_SIZE, threadFactory);
}
public static TimerUtils getInstance() {
if (mInstance == null) {
synchronized (TimerUtils.class) {
if (mInstance == null) {
mInstance = new TimerUtils();
}
}
}
return mInstance;
}
/**
* 执行定时器
*
* @param runnable 线程
* @param initialDelay 延迟执行时间
* @param period 执行的时间间隔
*/
public void startTimer(Runnable runnable, long initialDelay, long period) {
executor.scheduleAtFixedRate(runnable, initialDelay, period, TimeUnit.MILLISECONDS);
}
/**
* 取消定时器
*/
public void cancel() {
executor.shutdown();
}
/**
* 开启一个线程
*
* @param runnable 线程
*/
public void execute(Runnable runnable) {
executor.execute(runnable);
}
public void remove(Runnable runnable) {
BlockingQueue<Runnable> queue = executor.getQueue();
int i = runnable.hashCode();
System.out.println("i = " + i);
for (Runnable runnable1 : queue) {
System.out.println("runnable1 = " + runnable1.hashCode());
}
}
/**
* 延时执行一个线程
*
* @param runnable 线程
* @param delay 延时时间
*/
public void schedule(Runnable runnable, long delay) {
executor.schedule(runnable, delay, TimeUnit.MILLISECONDS);
}
}
//需要添加依赖
implementation 'org.apache.commons:commons-lang3:3.0'
网友评论