The previous lesson showed you how to define a class that manages thread pools and the tasks that run on them. This lesson shows you how to run a task on a thread pool. To do this, you add the task to the pool's work queue. When a thread becomes available, the ThreadPoolExecutor takes a task from the queue and runs it on the thread.

上一篇中向您展示了如何定义一个管理线程池以及在线程池上运行任务的类,这一篇将向您展示如何在一个线程池中运行任务。为了做到这一点,你需要将任务添加到线程池的工作队列中。当一个线程可用时,ThreadPoolExecutor会从队列中取出一个任务,并在线程上运行。

This lesson also shows you how to stop a task that's running. You might want to do this if a task starts, but then discovers that its work isn't necessary. Rather than wasting processor time, you can cancel the thread the task is running on. For example, if you are downloading images from the network and using a cache, you probably want to stop a task if it detects that an image is already present in the cache. Depending on how you write your app, you may not be able to detect this before you start the download.

这篇文章页向您展示如何停止一个正在运行的任务。这种情况是存在的,比如你启动了一个任务,后来发现这个任务不是必须的。为了节约处理器资源,你可以取消正在运行任务的线程。比如,如果你正在从网上下载一个图片,而且正在使用一个缓存,你忽然发现在缓存中已经有相同的图片了,此时你需要取消那个正在下载图片的任务。可能到你在下载这个图片之前,你都不知道在缓存中已经有相同的图片了。

Run a Task on a Thread in the Thread Pool


To start a task object on a thread in a particular thread pool, pass the Runnable to ThreadPoolExecutor.execute(). This call adds the task to the thread pool's work queue. When an idle thread becomes available, the manager takes the task that has been waiting the longest and runs it on the thread:

为了在一个线程池中开启一个任务,你只需传递runnable对象给 ThreadPoolExecutor.execute()即可。这个方法会将任务添加到线程池的工作队列。当线程池中有一个可用的线程时,ThreadPoolExecutor会选出一个等待时间最长的任务,交给这个可用的线程执行。

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());
...
}
...
}
...
}

  

When ThreadPoolExecutor starts a Runnable on a thread, it automatically calls the object's run() method。

ThreadPoolExecutor将runnable对象交给一个线程执行的时候,runnable对象的run方法会自定被调用。

Interrupt Running Code


To stop a task, you need to interrupt the task's thread. To prepare to do this, you need to store a handle to the task's thread when you create the task. For example:

为了停止一个正在运行的任务,你需要打断运行这个任务的线程。为了做到这一点,当初在创建任务时,你应该存储一个该线程的句柄。比如:

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());
...
}
...
}

  

To interrupt a thread, call Thread.interrupt(). Notice that Thread objects are controlled by the system, which can modify them outside of your app's process. For this reason, you need to lock access on a thread before you interrupt it, by placing the access in a synchronized block. For example:

为了能够取消一个线程,调用 Thread.interrupt()。请注意,线程是由系统来控制的,系统在你的应用的进程之外都能控制线程。正式如此,在你取消一个线程之前,一定锁住这个线程,锁住的方法就是将对这个线程的访问放在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();
}
}
}
}
...
}

  In most cases, Thread.interrupt() stops the thread immediately. However, it only stops threads that are waiting, and will not interrupt CPU or network-intensive tasks. To avoid slowing down or locking up the system, you should test for any pending interrupt requests before
attempting an operation :

在大多数的情况下, 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);
...

  

最新文章

  1. [LeetCode] Design Snake Game 设计贪吃蛇游戏
  2. css补充、JavaScript、Dom
  3. 移动web点5像素的秘密
  4. 从下往上看--新皮层资料的读后感 第四部分 来自神经元的设计-perceptron 感知机
  5. JAVA代码中加了Try...Catch的执行顺序
  6. linux命令:less
  7. UVALive 5966 Blade and Sword -- 搜索(中等题)
  8. day20 FORM补充(随时更新),F/Q操作,model之多对多,django中间件,缓存,信号
  9. Java 图形编程 二:布局管理器之顺序布局
  10. 设置Android默认锁定屏幕旋转
  11. Android NDK 环境搭建 + 测试例程(转)
  12. NOI2011 NOI嘉年华
  13. IO之内核buffer----&quot;buffer cache&quot;
  14. Service Manager流程,派BC_REPLY,唤醒FregServer流程,返回BR_TRANSACTION_COMPLETE,睡眠等待proc-&amp;gt;wait
  15. HDOJ3743&lt;分治&gt;
  16. 11. leetcode 283. Move Zeroes
  17. 从Unity中的Attribute到AOP(三)
  18. Git + Maven + Jenkins 实现分布式部署
  19. 使用iconv进行编码gb2312转utf8 转码失败的坑
  20. RPC框架-hessian学习

热门文章

  1. 微信小程序把玩(十六)form组件
  2. C#根据对象的指定字段去除重复值
  3. Android零基础入门第2节:Android 系统架构和应用组件那些事
  4. PopupWindow设置动画效果
  5. ShellExecute的跨平台实现OpenUrl
  6. Standard C 语言标准函数库速查(彩色的函数列表,十分清楚)
  7. elasticsearch.yml 常用参数说明
  8. python机器学习系列之环境搭建
  9. Flask学习之旅--数据库
  10. 【转载】Chrome使用自定义协议打开本地程序并运行IE打开网页