本文共 2925 字,大约阅读时间需要 9 分钟。
前面的教程指导您创建一个多线程管理器,向您展示如何定义一个管理线程池的类以及运行它们的任务。本课向您介绍如何在线程池上运行任务。为此,请将任务添加到池的工作队列中。当一个线程变得可用时, ThreadPoolExecutor从队列中取出一个任务并在线程上运行它。
本课还向您展示如何停止正在运行的任务。如果任务开始,您可能想要这样做,但随后发现其工作不是必需的。与其浪费处理器时间,您可以取消运行任务的线程。例如,如果您正在从网络下载图像并使用高速缓存,则如果检测到图像已存在于高速缓存中,您可能想要停止该任务。根据您编写应用程序的方式,您可能无法在开始下载之前检测到这一点。
要在特定线程池中的线程上启动任务对象,请传递 Runnable给ThreadPoolExecutor.execute()。该调用将任务添加到线程池的工作队列中。当空闲线程变为可用时,管理器将等待最长的任务并在线程上运行它:
public class PhotoManager { public void handleState(PhotoTask photoTask, int state) { switch (state) { // The task finished downloading the image case DOWNLOAD_COMPLETE: // Decodes the image mDecodeThreadPool.execute( photoTask.getPhotoDecodeRunnable()); ... } ... } ...}
当在线程上ThreadPoolExecutor启动时Runnable,它会自动调用对象的run()方法。
要停止任务,您需要中断任务的线程。为了做好准备,您需要在创建任务时将任务句柄存储到任务的线程中。例如:
class PhotoDecodeRunnable implements Runnable { // Defines the code to run for this task public void run() { /* * Stores the current Thread in the * object that contains PhotoDecodeRunnable */ mPhotoTask.setImageDecodeThread(Thread.currentThread()); ... } ...}
要中断一个线程,请致电Thread.interrupt()。请注意, Thread对象由系统控制,可以在应用程序的进程之外对其进行修改。出于这个原因,您需要在中断它之前锁定线程的访问权限,方法是将访问权限放在一个synchronized块中。例如
public class PhotoManager { public static void cancelAll() { /* * Creates an array of Runnables that's the same size as the * thread pool work queue */ Runnable[] runnableArray = new Runnable[mDecodeWorkQueue.size()]; // Populates the array with the Runnables in the queue mDecodeWorkQueue.toArray(runnableArray); // Stores the array length in order to iterate over the array int len = runnableArray.length; /* * Iterates over the array of Runnables and interrupts each one's Thread. */ synchronized (sInstance) { // Iterates over the array of tasks for (int runnableIndex = 0; runnableIndex < len; runnableIndex++) { // Gets the current thread Thread thread = runnableArray[taskArrayIndex].mThread; // if the Thread exists, post an interrupt to it if (null != thread) { thread.interrupt(); } } } } ...}
在大多数情况下,Thread.interrupt()立即停止线程。但是,它只会停止正在等待的线程,并且不会中断CPU或网络密集型任务。为避免减慢或锁定系统,应在尝试执行操作之前测试任何挂起的中断请求:
/* * Before continuing, checks to see that the Thread hasn't * been interrupted */if (Thread.interrupted()) { return;}...// Decodes a byte array into a Bitmap (CPU-intensive)BitmapFactory.decodeByteArray( imageBuffer, 0, imageBuffer.length, bitmapOptions);...
要了解更多关于Android上的多线程操作的信息,请参阅指南。
要尝试本指南中的概念,请下载。
Lastest Update:2018.04.17
QQ:94297366
微信打赏:
公众号推荐:
转载于:https://blog.51cto.com/4789781/2124452