Android 线程池 ThreadPoolExecutor
2015-10-13 15:43
351 查看
转载请标注来自:http://blog.csdn.net/u011241872/article/details/49099135
近写代码,经常遇到多线程,以前都不怎么理解,今天就把他总结一下:
线程池可以解决两个不同问题:由于减少了每个任务调用的开销,它们通常可以在执行大量异步任务时提供增强的性能,并且还可以提供绑定和管理资源(包括执行任务集时使用的线程)的方法。每个ThreadPoolExecutor 还维护着一些基本的统计数据,如完成的任务数。
先看一下ThreadPoolExecutor的结构
参数:
execute 方法提交的 Runnable 任务。
核心和最大池大小
ThreadPoolExecutor 将根据 corePoolSize和 maximumPoolSize设置的边界自动调整池大小。当新任务在方法
中提交时,如果运行的线程少于 corePoolSize,则创建新线程来处理请求,即使其他辅助线程是空闲的。如果运行的线程多于 corePoolSize 而少于 maximumPoolSize,则仅当队列满时才创建新线程。如果设置的 corePoolSize 和 maximumPoolSize 相同,则创建了固定大小的线程池。如果将 maximumPoolSize 设置为基本的无界值(如Integer.MAX_VALUE),则允许池适应任意数量的并发任务。在大多数情况下,核心和最大池大小仅基于构造来设置,不过也可以使用
和
保持活动时间
如果池中当前有多于 corePoolSize 的线程,则这些多出的线程在空闲时间超过 keepAliveTime 时将会终止。这提供了当池处于非活动状态时减少资源消耗的方法。如果池后来变得更为活动,则可以创建新的线程。也可以使用方法
动态地更改此参数。使用Long.MAX_VALUE
方法也可将此超时策略应用于核心线程。
构建线程池
线程池一共有四种构建方法,这边就不一一说明了:
在将来某个时间执行给定任务。可以在新线程中或者在现有池线程中执行该任务。 如果无法将任务提交执行,或者因为此执行程序已关闭,或者因为已达到其容量,则该任务由当前RejectedExecutionHandler
处理。
例子
运行结果:
创建线程池:1 创建线程池:2创建线程池:3执行线程任务:2执行线程任务:1执行线程任务:3创建线程池:4创建线程池:5执行线程任务:4执行线程任务:5.....
在AsyncTask中使用线程池
AsyncTask.executeOnExecutor(线程池);
如:AsyncTask为task;线程池为THREAD_POOL_EXECUTOR
task.executeOnExecutor(THREAD_POOL_EXECUTOR);这样就可以
线程池的内容还很多,希望我们一起来探讨,欢迎评论,哈哈哈!
近写代码,经常遇到多线程,以前都不怎么理解,今天就把他总结一下:
线程池可以解决两个不同问题:由于减少了每个任务调用的开销,它们通常可以在执行大量异步任务时提供增强的性能,并且还可以提供绑定和管理资源(包括执行任务集时使用的线程)的方法。每个ThreadPoolExecutor 还维护着一些基本的统计数据,如完成的任务数。
先看一下ThreadPoolExecutor的结构
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
参数:
corePoolSize- 池中所保存的线程数,包括空闲线程。
maximumPoolSize- 池中允许的最大线程数。
keepAliveTime- 当线程数大于核心时,此为终止前多余的空闲线程等待新任务的最长时间。
unit- keepAliveTime 参数的时间单位。
workQueue- 执行前用于保持任务的队列。此队列仅保持由
execute 方法提交的 Runnable 任务。
threadFactory- 执行程序创建新线程时使用的工厂。
handler- 由于超出线程范围和队列容量而使执行被阻塞时所使用的处理程序。抛出:
IllegalArgumentException- 如果 corePoolSize 或 keepAliveTime 小于 0,或者 maximumPoolSize 小于等于 0,或者 corePoolSize 大于 maximumPoolSize。
NullPointerException- 如果workQueue、threadFactory 或handler 为 null。
ThreadPoolExecutor 将根据 corePoolSize和 maximumPoolSize设置的边界自动调整池大小。当新任务在方法
execute(java.lang.Runnable)
中提交时,如果运行的线程少于 corePoolSize,则创建新线程来处理请求,即使其他辅助线程是空闲的。如果运行的线程多于 corePoolSize 而少于 maximumPoolSize,则仅当队列满时才创建新线程。如果设置的 corePoolSize 和 maximumPoolSize 相同,则创建了固定大小的线程池。如果将 maximumPoolSize 设置为基本的无界值(如Integer.MAX_VALUE),则允许池适应任意数量的并发任务。在大多数情况下,核心和最大池大小仅基于构造来设置,不过也可以使用
setCorePoolSize(int)
和
setMaximumPoolSize(int)进行动态更改。
保持活动时间
如果池中当前有多于 corePoolSize 的线程,则这些多出的线程在空闲时间超过 keepAliveTime 时将会终止。这提供了当池处于非活动状态时减少资源消耗的方法。如果池后来变得更为活动,则可以创建新的线程。也可以使用方法
setKeepAliveTime(long, java.util.concurrent.TimeUnit)
动态地更改此参数。使用Long.MAX_VALUE
TimeUnit.NANOSECONDS的值在关闭前有效地从以前的终止状态禁用空闲线程。默认情况下,保持活动策略只在有多于 corePoolSizeThreads 的线程时应用。但是只要 keepAliveTime 值非 0,
allowCoreThreadTimeOut(boolean)
方法也可将此超时策略应用于核心线程。
构建线程池
线程池一共有四种构建方法,这边就不一一说明了:
/** * 表示线程池保存线程为2 * 最大线程为Integer.MAX_VALUE * 空闲线程等待时间为3 * 任务队列为new ArrayBlockingQueue<Runnable>(3) */ ThreadPoolExecutor threadPool1 = new ThreadPoolExecutor(2, Integer.MAX_VALUE, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3));
在将来某个时间执行给定任务。可以在新线程中或者在现有池线程中执行该任务。 如果无法将任务提交执行,或者因为此执行程序已关闭,或者因为已达到其容量,则该任务由当前RejectedExecutionHandler
处理。
例子
import java.util.concurrent.ArrayBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; public class ThreadPool { private static int threadMaxNum = 10; public static void main(String[] args) { ThreadPoolExecutor threadPool = new ThreadPoolExecutor(2, Integer.MAX_VALUE, 3, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(3), new ThreadPoolExecutor.DiscardOldestPolicy()); for (int i = 1; i < threadMaxNum; i++) { final int nowData = i; System.out.println("创建线程池:" + nowData); // 执行一个Runnable threadPool.execute(new Runnable() { @Override public void run() { System.out.println("执行线程任务:" + nowData); } }); } } }
运行结果:
创建线程池:1 创建线程池:2创建线程池:3执行线程任务:2执行线程任务:1执行线程任务:3创建线程池:4创建线程池:5执行线程任务:4执行线程任务:5.....
在AsyncTask中使用线程池
AsyncTask.executeOnExecutor(线程池);
如:AsyncTask为task;线程池为THREAD_POOL_EXECUTOR
task.executeOnExecutor(THREAD_POOL_EXECUTOR);这样就可以
线程池的内容还很多,希望我们一起来探讨,欢迎评论,哈哈哈!
相关文章推荐
- Android水滴,小球粘性控件生成.
- android TextView超出屏幕加“...”
- 关于Android TouchDelegate源码解析
- android代码分析,及Terminal使用
- Android - Listener for incoming phone
- 如何使用android系统自带资源
- andfix 增量升级更新 热补丁修复
- Android的Touch Mode
- Android的事件处理1
- Android应用打破65K方法数限制:Conversion to Dalvik format failed: Unable to execute dex
- Android 之事件的分发和消费机制
- android调用JPush获取手机的注册码(Cordova环境)
- android开发could not find class解决方案
- ADB 命令大全[收集]
- Android轻量级ORM框架ActiveAndroid入门教程(转)
- android 内存溢出定位及解决
- Android打包失败Proguard returned with error code 1. See console
- AndroidStudio开发工具快捷键整理分享
- Android NotificationCompat通知消息
- Android开发总结笔记 四大组件之Activity(中) 1-2-2