Android的线程和线程池

线程在Android中是一个很重要的概念,从用途上说,线程分为主线程和子线程,主线程主要处理UI,子线程用于耗时操作。线程形态也有:AsyncTask,IntentService,HandlerThread…

主线程和子线程:

主线程是指进程所拥有的线程,默认情况下进程只有一个主线程。
主线程主要处理界面交互相关的逻辑,因为用户随时会和界面发生交互,因此主线程在任何时候都必须有较高的响应速度,否则会产生一种界面卡顿的感觉。所以要求主线程中不能执行耗时的任务,所以子线程就派上用场了。
子线程执行网络请求、I/O操作等,android3.0开始网络访问必须在子线程中进行。

线程形态:

~AsyncTask

AsyncTask 是轻量级的异步任务类,它可以在线程池中执行后台任务,然后把执行的进度和最终结果传递给主线程并在主线程中更新UI。从事实上讲,AsyncTask封装了Thread和Handle,通过AsyncTask可以更加方便执行后台任务以及在主线程中访问UI,但是 AsyncTask并不适合特别耗时的后台任务,对于特别耗时的任务来说,建议使用线程池。
AsynckTAsk中有两个线程池(SerialExecutor和THREAD_POOL_EXECUTOR)和一个Handler(IntenalHandler), SerialExecutor用于任务的排队,而THREAD_POOL_EXECUTOR用于真正执行任务。

    Public abstract class AsyncTask<Params,Progress,Result>
    Params表示参数的类型,Progress表示执行进度的类型,Result表示后台任务返回的结果类型。

AsyncTask 提供了四个核心方法:

  • onPreExecute(),在主线程中执行,在异步任务执行之前,此方法会被调用,一般用作一些准备工作。
  • doInBackgroud(Params…params),在线程池中执行,此方法用于执行异步任务,params参数表示异步任务输入的参数,在此方法中可以通过publishProgress方法更新任务进度,publishProgress方法会调用onProgressUpdate方法。另外次方法需要返回计算结果给onPostExecute方法。
  • onProgressUpdate(Progress…values),在主线程中执行。
  • onPostExecute(Result result),异步任务结束后的返回值,即doInBackgroud的返回值。

要求:
- AsyncTask对象必须在主线程中创建。
- Execute方法必须在UI线程中调用。
- 不要在程序中直接调用四个核心方法。
- 一个AsyncTask对象只能执行一次。
- Execute() 方法是串行执行任务, executeOnExecutor() 并行运行任务。

**AsyncTask简单用法**

http://blog.csdn.net/cjjky/article/details/6684959

~HandlerThread

可以使用Handler的Thread。
参考 :http://blog.csdn.net/lmj623565791/article/details/47079737
《Android开发艺术探索》第11章

~IntentService

  • intentService是一种特殊的服务,继承了Service并且是一个抽象类,因此必须创建它的子类才能使用IntentService。
  • 优先级高,不容易被系统杀死。
  • 用于执行耗时任务。
  • void onHandleIntent()从Intent参数中区分具体任务并执行这些任务。

~ThreadLocal

ThreadLocal是什么呢?其实ThreadLocal并非是一个线程的本地实现版本,它并不是一个Thread,而是threadlocalvariable(线程局部变量)。也许把它命名为ThreadLocalVar更加合适。线程局部变量(ThreadLocal)其实的功用非常简单,就是为每一个使用该变量的线程都提供一个变量值的副本,是Java中一种较为特殊的线程绑定机制,是每一个线程都可以独立地改变自己的副本,而不会和其它线程的副本冲突。
ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。
概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
http://my.oschina.net/garyun/blog/628581
http://blog.csdn.net/lufeng20/article/details/24314381

线程池:

~作用:

重用线程池中的线程,避免因为线程的创建和销毁带来的性能开销。
简单的管理,并提供定时执行以及间隔循环执行等功能。

~ThreadPoolExecutor线程池实现类

public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory) 
  • corePoolSize:线程池维护线程的最少数量,默认情况下,核心线程会在线程池中一直存活 。
  • maximumPoolSize:线程池维护线程的最大数量 。 keepAliveTime:线程池维护线程所允许的空闲时间 。
  • unit:线程池维护线程所允许的空闲时间的单位 。 workQueue:线程池所使用的缓冲队列 。
  • handler:线程池对拒绝任务的处理策略 。
  • threadFactory:线程工厂,为线程池提供创建新线程的功能。ThreadFactory是一个接口,它只有一个实现方法:Thread newThread(Runnable r)。

    ThreadPoolExecutor执行任务时遵守如下规则:

    1. 如果线程池中线程的数量未达到核心线程的数量,那么回直接启动一个核心线程。
    2. 如果线程池中线程数量超过已经达到或者超过核心线程的数量,那么任务会被插入到任务队列中排队等待执行。
    3. 如果步骤2中无法将任务插入到任务队列中,这往往是由于任务队列已满,这个时候如果线程未达到线程池规定的最大值,那么会立刻启动一个非核心线程来执行任务。
    4. 如果步骤3中线程数已经达到线程池所规定的是最大值,那么拒绝执行此任务,ThreadPoolExecutor会调用RejectedExecutionHandler的rejectedExecution方法来通知调用者。

推荐配置线程池(AsyncTask内置线程池)的规格:

  • 核心线程数等于CPU核心数+1;
  • 线程池的最大线程数为CPU核心数的2倍+1;
  • 核心线程默认无超时策略;
  • 任务队列的容量为128。

~线程池分类:

FixedThreadPool:

通过Executors的newFixedThreadPool方法创建。它是一种线程数量固定的线程池,当线程处于空闲状态时,它们并不会被回收,除非线程池被关闭了。当所有的线程都处于活动状态时,新任务都会处于等待状态,直到有线程空闲出来。由于FixedThreadPool只有核心线程并且这些核心线程不会被回收,这意味着它能够更快速响应外界的请求。fixedThreadPool中只有核心线程,并且这些核心线程没有超时机制,另外任务队列也是没有大小限制的。
源码:

public static ExecutorService newFixedThreadPool(int nThreads) {
        return new ThreadPoolExecutor(nThreads, nThreads,
                    0L, TimeUnit.MILLISECONDS,
                    new LinkedBlockingQueue<Runnable>());
}
CachedThreadPool:

通过Executors的newFixedThreadPool方法创建。
线程数量不定,线程数量Integer.MAX_VALUE 无限大。
空闲线程有超时机制,60秒。
任务任务都会立即执行。
源码:

public static ExecutorService newCachedThreadPool() {
return new ThreadPoolExecutor(0, Integer.MAX_VALUE,
                60L, TimeUnit.SECONDS,
                new SynchronousQueue<Runnable>());
}
ScheduledThreadPool:
  • 通过Executors的newFixedThreadPool方法创建。
  • 核心线程数量固定,非核心线程数量没有限制。
  • 非核心线程闲置时会被立即回收。
  • 用于执行定时任务和具有固定周期的重复任务
public static ScheduledExecutorService newScheduledThreadPool(int corePoolSize) {
    return new ScheduledThreadPoolExecutor(corePoolSize);
}
public ScheduledThreadPoolExecutor(int corePoolSize) {    
    super(corePoolSize, Integer.MAX_VALUE,
            DEFAULT_KEEPALIVE_MILLIS, MILLISECONDS,
            new DelayedWorkQueue());
}
SingleThreadExecutor
  • 通过Executors的newSingleThreadExecutor方法创建。
  • 只有一个核心线程。
  • 线程同步执行。
    源码:
public static ExecutorService newSingleThreadExecutor() {
    return new FinalizableDelegatedExecutorService
        (new ThreadPoolExecutor(1, 1,
            0L, TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<Runnable>()));
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值