Android线程池ThreadPoolExechtor

线程池的作用:

对多个线程进行统一地管理,避免资源竞争中出现的问题。对线程进行复用,线程在执行完任务后不会立刻销毁,而会等待另外的任务,这样就不会频繁地创建、销毁线程和调用GC。JAVA提供了一套完整的ExecutorService线程池创建的api,可创建多种功能不一的线程池,使用起来很方便。

创建线程池(基类ThreadPoolExecutor)

public ThreadPoolExecutor(int corePoolSize,
                              int maximumPoolSize,
                              long keepAliveTime,
                              TimeUnit unit,
                              BlockingQueue<Runnable> workQueue,
                              ThreadFactory threadFactory) {
        ...
    }

 

corepoolSize:核心线程数

maximumPoolSize: 线程池最大线程数量,非核心线程数=maxinumPoolSize - corepoolSize;

keepAliveTime:超时时长,作用于非核心线程(allowCoreThreadTimeOut被设置为true时也会同时作用于核心线程),闲置超时便被回收

unit:枚举类型,设置keepAliveTime的单位,有TimeUnit.MILLISECONDS(ms)、TimeUnit. SECONDS(s)等

workQueue:缓冲任务队列,线程池的execute方法会将Runnable对象存储起来

threadFactory::线程工厂,可用于设置线程名字等等,一般无须设置该参数

案例

//创建基本线程池
        final ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(3,5,1,TimeUnit.SECONDS,
                new LinkedBlockingQueue<Runnable>(100));

/**
  * 基本线程池使用
  */
 mThreadPoolExecute.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {

                for(int i = 0;i<30;i++){
                    final int finali = i;
                    Runnable runnable = new Runnable() {
                        @Override
                        public void run() {
                            try {
                                Thread.sleep(2000);
                                Log.d("Thread", "run: "+finali);
                                Log.d("当前线程:",Thread.currentThread().getName());
                            } catch (InterruptedException e) {
                                e.printStackTrace();
                            }
                        }
                    };
                    threadPoolExecutor.execute(runnable);
                }
            }
        });

 

(1)当currentSize<corePoolSize时,没什么好说的,直接启动一个核心线程并执行任务。

(2)当currentSize>=corePoolSize、并且workQueue未满时,添加进来的任务会被安排到workQueue中等待执行。

(3)当workQueue已满,但是currentSize<maximumPoolSize时,会立即开启一个非核心线程来执行任务。

(4)当currentSize>=corePoolSize、workQueue已满、并且currentSize>maximumPoolSize时,调用handler默认抛出RejectExecutionExpection异常。

其他基本线程

Android中最常见的四类具有不同特性的线程池分别为FixThreadPool、CachedThreadPool、ScheduleThreadPool以及SingleThreadExecutor。

1:FixedThreadPool (可重用固定线程数)

 1 /* 
 2 *@FixThreadPool介绍 
 3 *@author SEU_Calvin 
 4 * @date 2016/09/03 
 5 */  
 6 public static ExecutorService newFixThreadPool(int nThreads){  
 7     return new ThreadPoolExecutor(nThreads, nThreads, 0L, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());  
 8 }  
 9 //使用  
10 Executors.newFixThreadPool(5).execute(r);  

FixThreadPool只有核心线程,并且数量固定的,也不会被回收,所有线程都活动时,因为队列没有限制大小,新任务会等待执行。

3:CachedThreadPool (按需创建)

 1 /* 
 2 *@CachedThreadPool介绍 
 3 *@author SEU_Calvin 
 4 * @date 2016/09/03 
 5 */  
 6 public static ExecutorService newCachedThreadPool(int nThreads){  
 7     return new ThreadPoolExecutor(0, Integer.MAX_VALUE, 60L, TimeUnit. SECONDS, new SynchronousQueue<Runnable>());  
 8 }  
 9 //使用  
10 Executors.newCachedThreadPool().execute(r);  

 

(1)CachedThreadPool只有非核心线程,最大线程数非常大,所有线程都活动时,会为新任务创建新线程,否则利用空闲线程(60s空闲时间,过了就会被回收,所以线程池中有0个线程的可能)处理任务。

(2)任务队列SynchronousQueue相当于一个空集合,导致任何任务都会被立即执行。

(3)比较适合执行大量的耗时较少的任务。

3:SingleThreadPool(单个核线的fixed)

/* 
*@SingleThreadPool介绍 
*@author SEU_Calvin 
* @date 2016/09/03 
*/  
public static ExecutorService newSingleThreadPool (int nThreads){  
    return new FinalizableDelegatedExecutorService ( new ThreadPoolExecutor (1, 1, 0, TimeUnit. MILLISECONDS, new LinkedBlockingQueue<Runnable>()) );  
}  
//使用  
Executors.newSingleThreadPool ().execute(r);

 

由于只有一个核心线程,当被占用时,其他的任务需要进入队列等待。

4:ScheduledThreadPool(定时延时执行)

1 /* 
 2 *@ScheduledThreadPool介绍 
 3 *@author SEU_Calvin 
 4 * @date 2016/09/03 
 5 */  
 6 public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize){  
 7 return new ScheduledThreadPoolExecutor(corePoolSize);  
 8 }  
 9 public ScheduledThreadPoolExecutor(int corePoolSize){  
10 super(corePoolSize, Integer.MAX_VALUE, 0, NANOSECONDS, new DelayedQueue ());  
11 }  
12 //使用,延迟1秒执行,每隔2秒执行一次Runnable r  
13 Executors. newScheduledThreadPool (5).scheduleAtFixedRate(r, 1000, 2000, TimeUnit.MILLISECONDS);

核心线程数固定,非核心线程(闲着没活干会被立即回收)数没有限制。

 

各个线程池总结及适用场景

newCachedThreadPool:
适用:执行很多短期异步的小程序或者负载较轻的服务器

newFixedThreadPool:
适用:执行长期的任务,性能好很多

newSingleThreadExecutor:
适用:一个任务一个任务执行的场景

NewScheduledThreadPool:
适用:周期性执行任务的场景

线程池其它方法:

1.shutDown()  关闭线程池,不影响已经提交的任务

2.shutDownNow() 关闭线程池,并尝试去终止正在执行的线程

3.allowCoreThreadTimeOut(boolean value) 允许核心线程闲置超时时被回收

4.submit 一般情况下我们使用execute来提交任务,但是有时候可能也会用到submit,使用submit的好处是submit有返回值。

5.beforeExecute() - 任务执行前执行的方法

6.afterExecute() -任务执行结束后执行的方法

7.terminated() -线程池关闭后执行的方法


https://www.jianshu.com/p/7b2da1d94b42

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值