您的位置:首页 > 移动开发 > Android开发

Android的线程和线程池

2016-03-08 10:57 411 查看
线程在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简单用法**


/article/1392373.html

~HandlerThread

可以使用Handler的Thread。

参考 :/article/1369222.html

《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

/article/3617971.html

线程池:

~作用:

重用线程池中的线程,避免因为线程的创建和销毁带来的性能开销。

简单的管理,并提供定时执行以及间隔循环执行等功能。

~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执行任务时遵守如下规则:

如果线程池中线程的数量未达到核心线程的数量,那么回直接启动一个核心线程。

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

如果步骤2中无法将任务插入到任务队列中,这往往是由于任务队列已满,这个时候如果线程未达到线程池规定的最大值,那么会立刻启动一个非核心线程来执行任务。

如果步骤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>()));
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: