Android 的线程跟线程池

26 篇文章 0 订阅

Android 的线程跟线程池

Android中线程分为主线程(进程所拥有的一个默认线程)跟子线程,主线程主要处理和界面相关的操作,而子线程则处理一些耗时操作,如从网络加载图片(从android3.0开始网络请求需放到子线程中处理),I/O操作等。(若主线程中执行耗时操作程序容易出现ANR)

线程:线程是操作系统调度的最小单元,也是一种受限制的系统资源,线程不能无限的产生,线程的创建跟销毁都会有相应的开销(这就导致了线程池的诞生)。注意线程不可能做到绝对的并行。

线程池:一个线程池会缓存一定数量的线程,并且线程池可以复用其内部的某些线程,以减少线程创建和销毁时的开销。

Android 线程形式(简单列举几例)

AsyncTask

AsyncTask是轻量级的异步任务类,其内部封装了Thread跟Handler(其并不适合进行特别耗时的后台任务)

其核心方法有4个:

onPreExecute() ,该方法是在主线程中执行,在异步任务开始之前做一些准备工作。

doInBackground(),该方法在线程池中执行,用于执行异步任务。另外此方法里面可以调用publishProgress方法来更新任务的进度(publishProgress方法会调用onProgressUpdate方法)。

onProgressUpdate(),该方法在主线程中执行,当任务进度改变时此方法会被调用。

onPostExecute()方法,在主线程中执行,任务完成之后调用。

另外还有onCancelled()方法,它在主线程中执行,用于取消异步任务。

使用AsynvTask时需注意:

1  AsyncTask的类必须在主线程中加载

2  AsyncTask对象必须在主线程中创建

3  execute方法必须在主线程中调用

4  不要在程序中直接调用onPreExecute,doInBackground,onProgressUpdate,onPostExecute方法。

5  一个AsyncTask对象只能执行一次。

HandlerThread

HandlerThread继承自Thread,特点是其run方法是一个无限循环的,当不需要使用HandlerThread时可以通过它的quit方法或者quitSafely方法终止线程。

其run的源码如下:

@Override
 public void run() {
    mTid = Process.myTid();
    Looper.prepare();
    synchronized (this) {
        mLooper = Looper.myLooper();
        notifyAll();
    }
    Process.setThreadPriority(mPriority);
    onLooperPrepared();
     Looper.loop();
    mTid = -1;
}


IntentService

IntentService是一种特殊的Service,是继承自service的抽象类。可用于执行一些后台耗时的操作,优点是当任务执行完后它会自动停止。(另外由于IntentService继承了service所以其优先级较高,不易被系统杀死)。用代码来理解其用法:

public class SelfIntentSerivce extends IntentService {
 
         public SelfIntentSerivce() {
              super("SelfIntentService");
         }
         @Override
         protected void onHandleIntent(Intent intent) {
                   Stringstr=intent.getExtras().getString("service");
                   LogUtil.d("intent-serviceonHandleIntent"+str);
         }
         @Override
         public void onCreate() {
              super.onCreate();
              LogUtil.d("intent-servicecreate");
         }
         @Override
         public void onStart(Intent intent, int startId) {
              super.onStart(intent,startId);
              LogUtil.d("intent-servicestart "+intent.getExtras().getString("service"));
         }
         @Override
         publicvoid onDestroy() {
              super.onDestroy();
              LogUtil.d("intent-servicedestory");
         }
}


 

Intent intent=new Intent(this,SelfIntentSerivce.class);
intent.putExtra("service","hello");
startService(intent);


运行结果如下:


当IntentService任务执行完成后其会自动结束。

Android的线程池

线程池的优点有:

1可以重用线程池中的线程以减少线程创建跟销毁带来的性能开销

2克有效控制线程池的最大并发数,避免大量线程之间相互抢占系统资源导致阻塞

3能管理其内部的线程,并提供定时执行跟指定时间间隔执行。

ThreadPoolExecutor

ThreadPoolExecutor是线程池的实现类,其构造方法提供一系列参数来配置线程池。

其有多个构造方法,举一个为例:

public ThreadPoolExecutor(int corePoolSize,
                      int maximumPoolSize,
                      long keepAliveTime,
                      TimeUnit unit,
                      BlockingQueue<Runnable> workQueue,
                      ThreadFactorythreadFactory) {
 this(corePoolSize, maximumPoolSize,keepAliveTime, unit, workQueue,
            threadFactory, defaultHandler);
 }


corePoolSize:代表线程池的核心线程数,默认情况下,核心线程会在线程池中一直存活,即便是核心线程处于闲置状态。若ThreadPoolExecutor的allowCoreThreadTimeOut属性设置为true,那么闲置的核心线程在等待新任务的到来时会有超时策略,这个时间间隔由keepAliveTime决定,当等待时间超过keepAliveTime所指定的时间后,核心线程就会被终止。

maximumPoolSize:线程池的最大线程数,当活动的线程达到这个数值后,后续的新任务将会被阻塞。

keepAliveTime:非核心线程闲置时的超时时长,超过这个时间,非核心线程会被回收,当ThreadPoolExecutor的allowCoreThreadTimeOut设置为true时,其同样会作用于核心线程。

Unit:用于指定keepAliveTime参数的时间单位,有TimeUnit.MILLISECOND,TimeUnit.SECOND等。

WorkQueue:线程池中的任务队列,通过线程池的execute方法提交的Runnable对象会存储在这个参数中。

threadFactory:线程工厂,为线程池提供创建新线程的功能。

 

ThreadPoolExecutor执行任务规则如下:

1: 线程池中的线程数未达到核心线程的数量,那么会直接启动一个核心线程来执行任务。

2 :线程池中的线程数已经达到或超过核心线程数量,那么任务会被插到任务队列中排队等待执行

3: 如果2中的任务无法插到任务队列中(比如任务队列满了),这时候如果线程数量未达到线程池规定的最大值,则会启动一个非核心线程来执行。

4 :如果 3中线程数已经达到线程池最大值,那么就会拒绝执行这个任务,ThreadPoolExecutor会调用RejectedExecutionHandler的rejectExecution方法来通知调用者。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值