Android的线程和线程池
2016-03-08 10:57
411 查看
线程在Android中是一个很重要的概念,从用途上说,线程分为主线程和子线程,主线程主要处理UI,子线程用于耗时操作。线程形态也有:AsyncTask,IntentService,HandlerThread…
主线程主要处理界面交互相关的逻辑,因为用户随时会和界面发生交互,因此主线程在任何时候都必须有较高的响应速度,否则会产生一种界面卡顿的感觉。所以要求主线程中不能执行耗时的任务,所以子线程就派上用场了。
子线程执行网络请求、I/O操作等,android3.0开始网络访问必须在子线程中进行。
AsynckTAsk中有两个线程池(SerialExecutor和THREAD_POOL_EXECUTOR)和一个Handler(IntenalHandler), SerialExecutor用于任务的排队,而THREAD_POOL_EXECUTOR用于真正执行任务。
AsyncTask 提供了四个核心方法:
onPreExecute(),在主线程中执行,在异步任务执行之前,此方法会被调用,一般用作一些准备工作。
doInBackgroud(Params…params),在线程池中执行,此方法用于执行异步任务,params参数表示异步任务输入的参数,在此方法中可以通过publishProgress方法更新任务进度,publishProgress方法会调用onProgressUpdate方法。另外次方法需要返回计算结果给onPostExecute方法。
onProgressUpdate(Progress…values),在主线程中执行。
onPostExecute(Result result),异步任务结束后的返回值,即doInBackgroud的返回值。
要求:
- AsyncTask对象必须在主线程中创建。
- Execute方法必须在UI线程中调用。
- 不要在程序中直接调用四个核心方法。
- 一个AsyncTask对象只能执行一次。
- Execute() 方法是串行执行任务, executeOnExecutor() 并行运行任务。
/article/1392373.html
参考 :/article/1369222.html
《Android开发艺术探索》第11章
优先级高,不容易被系统杀死。
用于执行耗时任务。
void onHandleIntent()从Intent参数中区分具体任务并执行这些任务。
ThreadLocal是如何做到为每一个线程维护变量的副本的呢?其实实现的思路很简单,在ThreadLocal类中有一个Map,用于存储每一个线程的变量的副本。
概括起来说,对于多线程资源共享的问题,同步机制采用了“以时间换空间”的方式,而ThreadLocal采用了“以空间换时间”的方式。前者仅提供一份变量,让不同的线程排队访问,而后者为每一个线程都提供了一份变量,因此可以同时访问而互不影响。
http://my.oschina.net/garyun/blog/628581
/article/3617971.html
简单的管理,并提供定时执行以及间隔循环执行等功能。
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。
源码:
线程数量不定,线程数量Integer.MAX_VALUE 无限大。
空闲线程有超时机制,60秒。
任务任务都会立即执行。
源码:
核心线程数量固定,非核心线程数量没有限制。
非核心线程闲置时会被立即回收。
用于执行定时任务和具有固定周期的重复任务
只有一个核心线程。
线程同步执行。
源码:
主线程和子线程:
主线程是指进程所拥有的线程,默认情况下进程只有一个主线程。主线程主要处理界面交互相关的逻辑,因为用户随时会和界面发生交互,因此主线程在任何时候都必须有较高的响应速度,否则会产生一种界面卡顿的感觉。所以要求主线程中不能执行耗时的任务,所以子线程就派上用场了。
子线程执行网络请求、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>())); }
相关文章推荐
- android中tesseract-ocr的介绍
- android:imeOptions属性 (转载)
- android应用程序静态分析工具androguard初体验(二)
- Android推送技术研究
- Android布局案例之人人android九宫格
- android布局优化
- Android 开发绕不过的坑:你的 Bitmap 究竟占多大内存?
- 4.10 从头学Android之多媒体--使用MediaPlayer和SurfaceView播放视频
- android 常用动画
- Android M 新的运行时权限开发者需要知道的一切
- ubuntu 下androidsdk 更新
- android apk 源码 的 破译(反编译)
- android倒计时控件示例
- android:layout_weight权重分析
- Android 壁纸设置代码 详解
- android收起软键盘
- android监听事件的方式
- android端StarIO热敏打印机打印小票
- Android Context上下文(几种的对比,应用场景)
- Error inflating class android.support.v7.widget.Toolbar