如何在安卓中使用线程池(ThreadPoolExecutor)
来源:互联网 发布:mac cocos2dx lua 编辑:程序博客网 时间:2024/06/09 21:30
如何在安卓中使用线程池(ThreadPoolExecutor)
标签(空格分隔): 翻译计划
原文链接地址:Using ThreadPoolExecutor in Android
这篇文章将会覆盖线程池、线程池执行者、和怎么把他们使用到安卓里面。我们将会介绍这些主题,并且会附有许多示例代码。
线程池(Thread Pools)
一个线程池管理者一个工作线程池(线程池确定的个数取决于我们如何实现的)
一个任务队列保持着等待的任务,这些任务将会被线程池中的等待线程执行。生产者把任务添加到队列中,而工作线程作为消费者,只要有空闲的线程准备好执行任务,就从任务队列中取出任务并且消耗掉它。
线程执行者(ThreadPoolExecutor)
ThreadPoolExecutor则使用线程池中的一个线程来执行给定的任务
创建一个线程执行者:
ThreadPoolExecutor executor = ThreadPoolExecutor( int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue);
这些参数的含义
- 1、corePoolSize
- 线程池中的最小线程个数,最初的线程池个数初始化是0个,但是当我们把任务添加到队列中的时候,一个新的线程将会被创建,如果有空线程,但是线程数低于corePoolSize,那么新的线程将会被继续创建
- 2、maximumPoolSize
- 线程池中允许创建的最大线程个数,如果这个数字超过了corePolSize,并且currentPoolSize>=corePoolSize,那么只有当队列满的时候才会去创建新的工作线程。
- 3、keepAliveTime
- 线程存活时间,当线程数大于核心线程(工作线程),那么非核心线程(多于的空闲线程)将等待新的任务,如果这些线程在该参数定义的时间内没有得到任务去执行,将会被销毁。
- 4、unit
- 线程存活时间keepAliveTime的时间单位
- 5、workQueue
- 工作队列,将会持有持续运行任务,这里将会展现BlockingQueue
安卓和Java中为什么会用到线程池
- 1、这是一个强大的任务执行框架,支持队列中的任务添加,任务取消和任务优先级排序
- 2、它可以减少线程创建的开销,因为他会在线程池中管理所需要的线程
在安卓中使用ThreadPoolExecutor
首先,创建一个PriorityThreadFactory
public class PriorityThreadFactory implements ThreadFactory { private final int mThreadPriority; public PriorityThreadFactory(int threadPriority) { mThreadPriority = threadPriority; } @Override public Thread newThread(final Runnable runnable) { Runnable wrapperRunnable = new Runnable() { @Override public void run() { try { Process.setThreadPriority(mThreadPriority); } catch (Throwable t) { } runnable.run(); } }; return new Thread(wrapperRunnable); }}
创建一个MainThreadExecutor
public class MainThreadExecutor implements Executor { private final Handler handler = new Handler(Looper.getMainLooper()); @Override public void execute(Runnable runnable) { handler.post(runnable); }}
创建一个DefaultExecutorSupplier
/** Singleton class for default executor supplier*/public class DefaultExecutorSupplier{ /* * Number of cores to decide the number of threads */ public static final int NUMBER_OF_CORES = Runtime.getRuntime().availableProcessors(); /* * thread pool executor for background tasks */ private final ThreadPoolExecutor mForBackgroundTasks; /* * thread pool executor for light weight background tasks */ private final ThreadPoolExecutor mForLightWeightBackgroundTasks; /* * thread pool executor for main thread tasks */ private final Executor mMainThreadExecutor; /* * an instance of DefaultExecutorSupplier */ private static DefaultExecutorSupplier sInstance; /* * returns the instance of DefaultExecutorSupplier */ public static DefaultExecutorSupplier getInstance() { if (sInstance == null) { synchronized(DefaultExecutorSupplier.class){ sInstance = new DefaultExecutorSupplier(); } return sInstance; } /* * constructor for DefaultExecutorSupplier */ private DefaultExecutorSupplier() { // setting the thread factory ThreadFactory backgroundPriorityThreadFactory = new PriorityThreadFactory(Process.THREAD_PRIORITY_BACKGROUND); // setting the thread pool executor for mForBackgroundTasks; mForBackgroundTasks = new ThreadPoolExecutor( NUMBER_OF_CORES * 2, NUMBER_OF_CORES * 2, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), backgroundPriorityThreadFactory ); // setting the thread pool executor for mForLightWeightBackgroundTasks; mForLightWeightBackgroundTasks = new ThreadPoolExecutor( NUMBER_OF_CORES * 2, NUMBER_OF_CORES * 2, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), backgroundPriorityThreadFactory ); // setting the thread pool executor for mMainThreadExecutor; mMainThreadExecutor = new MainThreadExecutor(); } /* * returns the thread pool executor for background task */ public ThreadPoolExecutor forBackgroundTasks() { return mForBackgroundTasks; } /* * returns the thread pool executor for light weight background task */ public ThreadPoolExecutor forLightWeightBackgroundTasks() { return mForLightWeightBackgroundTasks; } /* * returns the thread pool executor for main thread task */ public Executor forMainThreadTasks() { return mMainThreadExecutor; }}
现在在你的代码逻辑中使用吧
/** Using it for Background Tasks*/public void doSomeBackgroundWork(){ DefaultExecutorSupplier.getInstance().forBackgroundTasks() .execute(new Runnable() { @Override public void run() { // do some background work here. } });}/** Using it for Light-Weight Background Tasks*/public void doSomeLightWeightBackgroundWork(){ DefaultExecutorSupplier.getInstance().forLightWeightBackgroundTasks() .execute(new Runnable() { @Override public void run() { // do some light-weight background work here. } });}/** Using it for MainThread Tasks*/public void doSomeMainThreadWork(){ DefaultExecutorSupplier.getInstance().forMainThreadTasks() .execute(new Runnable() { @Override public void run() { // do some Main Thread work here. } });}
通过这种方式,我们可以创建不同的线程池来服务于网络任务/IO任务/(后台)耗时任务、还有其他任务。
如何取消任务
当我们取消一个任务的时候,我们需要得到一个Future,而不是直接执行,因此我们需要使用submit,这样将会返回一个Future,然后我们就可以使用返回回来的Future来取消任务.
/** Get the future of the task by submitting it to the pool*/Future future = DefaultExecutorSupplier.getInstance().forBackgroundTasks() .submit(new Runnable() { @Override public void run() { // do some background work here. }});/** cancelling the task*/future.cancel(true);
如何对一个任务设置优先级
假设一个任务队列中有20个任务,而我们创建的线程池只有四个可用于工作的线程,我们可以基于优先级来执行任务,毕竟我们一次只能执行4个任务。
假设我们需要在队列中首先执行最后一个任务,我们可以为这个线程设置IMMEDIATE优先级,以便于我们在队列中获取新任务的时候,将会执行此任务(因为这个标志的任务具有最高优先级)
要设置任务的优先级,我们需要创建一个线程池执行器
创建枚举优先级
/** * Priority levels */public enum Priority { /** * NOTE: DO NOT CHANGE ORDERING OF THOSE CONSTANTS UNDER ANY CIRCUMSTANCES. * Doing so will make ordering incorrect. */ /** * Lowest priority level. Used for prefetches of data. 低级优先级 */ LOW, /** * Medium priority level. Used for warming of data that might soon get visible. 中端优先级 */ MEDIUM, /** * Highest priority level. Used for data that are currently visible on screen. 高优先级 */ HIGH, /** * Highest priority level. Used for data that are required instantly(mainly for emergency). 最高优先级 */ IMMEDIATE;}
创建一个优先级线程
public class PriorityRunnable implements Runnable { private final Priority priority; public PriorityRunnable(Priority priority) { this.priority = priority; } @Override public void run() { // nothing to do here. } public Priority getPriority() { return priority; }}
创建一个PriorityThreadPoolExecutor(优先级线程执行者)继承于ThreadPoolExecutor,我们还需要创建一个PriorityFutureTask,实现Comparable接口
public class PriorityThreadPoolExecutor extends ThreadPoolExecutor { public PriorityThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, ThreadFactory threadFactory) { super(corePoolSize, maximumPoolSize, keepAliveTime, unit,new PriorityBlockingQueue<Runnable>(), threadFactory); } @Override public Future<?> submit(Runnable task) { PriorityFutureTask futureTask = new PriorityFutureTask((PriorityRunnable) task); execute(futureTask); return futureTask; } private static final class PriorityFutureTask extends FutureTask<PriorityRunnable> implements Comparable<PriorityFutureTask> { private final PriorityRunnable priorityRunnable; public PriorityFutureTask(PriorityRunnable priorityRunnable) { super(priorityRunnable, null); this.priorityRunnable = priorityRunnable; } /* * compareTo() method is defined in interface java.lang.Comparable and it is used * to implement natural sorting on java classes. natural sorting means the the sort * order which naturally applies on object e.g. lexical order for String, numeric * order for Integer or Sorting employee by there ID etc. most of the java core * classes including String and Integer implements CompareTo() method and provide * natural sorting. */ @Override public int compareTo(PriorityFutureTask other) { Priority p1 = priorityRunnable.getPriority(); Priority p2 = other.priorityRunnable.getPriority(); return p2.ordinal() - p1.ordinal(); } }}
首先,在DefaultExecutorSupplier,而不是ThreadPoolExecutor中,向一下使用方式使用PriorityThreadPoolExecutor.
public class DefaultExecutorSupplier{private final PriorityThreadPoolExecutor mForBackgroundTasks;private DefaultExecutorSupplier() { mForBackgroundTasks = new PriorityThreadPoolExecutor( NUMBER_OF_CORES * 2, NUMBER_OF_CORES * 2, 60L, TimeUnit.SECONDS, backgroundPriorityThreadFactory ); }}
给一个如何给一个任务设置优先级的例子
/** do some task at high priority*/public void doSomeTaskAtHighPriority(){ DefaultExecutorSupplier.getInstance().forBackgroundTasks() .submit(new PriorityRunnable(Priority.HIGH) { @Override public void run() { // do some background work here at high priority. }});}
通过这种方式,我们就可以创建一个具有优先级的任务,上述所有使用方式同样适用于Java Applications
这里给一个我自己封装的安卓网络工作的依赖库Android Networking Library
如果想知道更详细的实现,可以查看DefaultExecutorSupplier.java这个类在Android Networking here.
我希望这些知识对于你有些帮助
感谢您阅读本文。
如果您发现它有用,请务必点击下面的❤推荐这篇文章。
如果想知道更多的关于程序设计方面的知识, follow me and Mindorks ,以便于我们更新新的技术文章的时候会通知到你。
Check out all the Mindorks best articles here.
Also, Let’s become friends on Twitter, Linkedin, Github and Facebook.
当然了最后的这些推荐都是需要翻墙的,这个就需要大家墙一下了哈.这里推荐给大家一个翻墙的网址,需要收费的,但是非常便宜的(最低的套餐一个月15G/1.5元 一年才18(现在搞活动)),可以看一下
- 如何在安卓中使用线程池(ThreadPoolExecutor)
- 线程池ThreadPoolExecutor使用
- java线程池ThreadPoolExecutor 如何与 AsyncTask() 组合使用
- 线程池ThreadPoolExecutor使用简介
- 线程池ThreadPoolExecutor使用简介
- 线程池ThreadPoolExecutor使用简介
- 线程池ThreadPoolExecutor使用简介
- 线程池ThreadPoolExecutor使用简介
- 线程池ThreadPoolExecutor使用简介
- 线程池ThreadPoolExecutor使用简介
- 线程池ThreadPoolExecutor使用简介
- 线程池ThreadPoolExecutor使用简介
- 线程池ThreadPoolExecutor使用简介
- 线程池ThreadPoolExecutor使用简介
- 线程池ThreadPoolExecutor使用简介
- 线程池ThreadPoolExecutor使用简介
- ThreadPoolExecutor线程池的使用
- ThreadPoolExecutor线程池使用介绍
- SSL1333 地鼠的困境
- POJ 3083 (bfs + dfs)
- webpack学习笔记-5-extract-text-webpack-plugin
- 基因组信息学参考习题
- bot framework2——与用户交互
- 如何在安卓中使用线程池(ThreadPoolExecutor)
- java用递归删除目录
- git查看远程仓库信息
- Playgrounds配件Parrot Education的深入发掘(一)
- LeetCode_linked-list-cycle-ii
- mysql语法
- 二分搜索——在有序数组中找到目标函数出来的最左端的位置
- 学习记录:接口功能配置之 Settings及QuickSettings
- POJ 1269 Intersecting Lines(直线相交判断,求交点)