在Android线程池里运行代码任务实例

本节展示如何在线程池里执行任务。流程是,添加一个任务到线程池的工作队列,当有线程可用时(执行完其他任务,空闲,或者还没执行任务),ThreadPoolExecutor会从队列里取任务,并在线程里运行。
本课同时向你展示了如何停止正在运行的任务。

在线程池里的线程上执行任务

在ThreadPoolExecutor.execute()里传入 Runnable对象启动任务。这个方法会把任务添加到线程池工作队列。当有空闲线程时,管理器会取出等待最久的任务,在线程上运行。

代码如下:

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()方法。

中断正在运行的代码

要停止任务,你需要中断任务的进程。你需要在创建任务的时候,保存一个当前线程的handle.
如:

代码如下:

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()就可以了。提示:线程对象是系统控制的,可以在你的app进程外被编辑。因为这个原因,你需要在中断它前加访问锁,放到一个同步块里:

代码如下:

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或network-intensive任务。为了避免系统变慢,你应该在开始尝试操作前测试等待中断的请求。

代码如下:

/*
 * 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);
...

(0)

相关推荐

  • Android中创建多线程管理器实例

    如果你要反复执行一个任务,用不同的数据集(参数不同),但一次只要一个执行(任务是单线程的),IntentService符合你的需求.当需要在资源可用时自动执行任务,或允许多任务同时执行,你需要一个线程管理器管理你的线程.ThreadPoolExecutor,会维护一个队列,当它的线程池有空时,从队列里取任务,并执行.要运行任务,你要做的就是把它加到队列里. 线程池可以并联运行一个任务的多个实例,所以你要保存代码线程安全.能被多线程访问的变量需要同步块.更多信息,见Processes and Th

  • Android4.0平板开发之隐藏底部任务栏的方法

    本文实例讲述了Android4.0平板开发之隐藏底部任务栏的方法.分享给大家供大家参考,具体如下: 复制代码 代码如下: getWindow().getDecorView().setSystemUiVisibility(View.SYSTEM_UI_FLAG_HIDE_NAVIGATION);//隐藏底部任务栏代码 上边已验证 下边百度过来的 showBar显示任务栏 closeBar隐藏任务栏 前提:需要ROOT权限 public static void showBar() { try { P

  • Android 定时任务过程详解

    在Android开发中,通过以下三种方法定时执行任务: 一.采用Handler与线程的sleep(long)方法(不建议使用,java的实现方式) 二.采用Handler的postDelayed(Runnable, long)方法(最简单的android实现) 三.采用Handler与timer及TimerTask结合的方法(比较多的任务时建议使用) android里有时需要定时循环执行某段代码,或者需要在某个时间点执行某段代码,这个需求大家第一时间会想到Timer对象,没错,不过我们还有更好的

  • android异步任务设计思详解(AsyncTask)

    这里说有设计思想是我根据查看Android源代码提炼出来的代码逻辑,所以不会跟Google工程师的原始设计思想100%符合(也有可能是0%),但是本文一定可以帮助你理解AsyncTask,也可能有一些你以前没有发现的内容. 大家都知道,Android的主线程(又叫UI线程,线程ID为1)有一些限制策略,使得主线程有些事做不了,比如访问网络就不允许,否则就是报,但在2.3之后的版本,你可以通过添加以下代码更改其限制策略,从而强制使得主线程可以访问网络: 复制代码 代码如下: if (android

  • Android编程实现任务管理器的方法

    本文实例讲述了Android编程实现任务管理器的方法.分享给大家供大家参考,具体如下: 任务管理器可以实现的功能有: 1.查看当前系统下运行的所有的进程 2.可以查看每个进程的进程号.版本号以及内存占用情况 3.杀死进程(可以杀死全部进程或者杀死指定的进程) 4.查看系统剩余内存 效果图: 杀死全部进程 实现思路: ActivityManager类可以获取到当前系统的所有进程,以及每个进程的信息,也可以杀死某个进程, ActivityManager.getRunningAppProcesses(

  • Android 获取正在运行的任务和服务的小例子

    要获取正在运行的任务,首先需要声明一个活动对象管理器(ActivityManager) 所有的活动任务都属于此,然后通过获取服务可以得到所有的活动对象,然后通过活动对象可以得到所有运行的任务和服务,当然要获取服务和任务是使用不同的方法,但是方式是一样的.下面是获取代码:代码 复制代码 代码如下: void getTask() {        ActivityManager activityManager;        try {            activityManager = (A

  • 浅析Android文件管理器(项目一)

    文件管理器是管理文件的软件,帮助用户处理日常工作,管理储存在本地和网络中的文件.所有文件管理器都提供了基本的操作如创建.打开.查看.编辑.移动和删除文件.许多Android文件管理器还提供了额外功能,如网络连接.应用程序管理.存档和压缩处理.搜索等. 今晚就写了res下面那些文件,因为在编写逻辑的时候如果资源文件夹没有的话,会非常的苦恼的.所以学习的时候总是会先把资源编写完毕,再开始编写逻辑. 然后我自己也总结一下今晚学了什么吧. IDE : Android Studio 惯例,上代码. 先是

  • android在异步任务中关闭Cursor的代码方法

    查询数据会比较耗时,所以我们想把查询数据放在一个异步任务中,查询结果获得Cursor,然后在onPostExecute (Cursor result)方法中设置Adapter,我们可能会想到使用Activity的managedQuery来生成Cursor,这样Cursor就会与Acitivity的生命周期一致了,多么完美的解决方法!然而事实上managedQuery也有很大的局限性,managedQuery生成的Cursor必须确保不会被替换,因为可能很多程序事实上查询条件都是不确定的,因此我们

  • 在Android线程池里运行代码任务实例

    本节展示如何在线程池里执行任务.流程是,添加一个任务到线程池的工作队列,当有线程可用时(执行完其他任务,空闲,或者还没执行任务),ThreadPoolExecutor会从队列里取任务,并在线程里运行. 本课同时向你展示了如何停止正在运行的任务. 在线程池里的线程上执行任务 在ThreadPoolExecutor.execute()里传入 Runnable对象启动任务.这个方法会把任务添加到线程池工作队列.当有空闲线程时,管理器会取出等待最久的任务,在线程上运行. 复制代码 代码如下: publi

  • Java 定时器(Timer)及线程池里使用定时器实例代码

    java Timer定时器 简单实例代码: public class Test { public static void main(String[] args) { // Timer定时器 Timer mTimer = new Timer(); MyTack myTack = new MyTack(); mTimer.schedule(myTack, 2000, 3000);//第一个参数是需要执行的任务 第二个参数是延迟多少时间最开始执行,第三个参数是执行完后多少时间后进行再次执行是一个周期性

  • java线程池:获取运行线程数并控制线程启动速度的方法

    在java里, 我们可以使用Executors.newFixedThreadPool 来创建线程池, 然后就可以不停的创建新任务,并用线程池来执行了. 在提交任务时,如果线程池已经被占满,任务会进到一个队列里等待执行. 这种机制在一些特定情况下会有些问题.今天我就遇到一种情况:创建线程比线程执行的速度要快的多,而且单个线程占用的内存又多,所以很快内存就爆了. 想了一个办法,就是在提交任务之前,先检查目前正在执行的线程数目,只有没把线程池占满的时候在去提交任务. 代码很简单: int thread

  • Android线程池源码阅读记录介绍

    今天面试被问到线程池如何复用线程的?当场就懵掉了...于是面试完毕就赶紧打开源码看了看,在此记录下: 我们都知道线程池的用法,一般就是先new一个ThreadPoolExecutor对象,再调用execute(Runnable runnable)传入我们的Runnable,剩下的交给线程池处理就行了,于是这次我就从ThreadPoolExecutor的execute方法看起: public void execute(Runnable command) { if (command == null)

  • Python快速实现一个线程池的示例代码

    目录 楔子 Future 对象 提交函数自动创建 Future 对象 future.set_result 到底干了什么事情 提交多个函数 使用 map 来提交多个函数 按照顺序等待执行 取消一个函数的执行 函数执行时出现异常 等待所有函数执行完毕 小结 楔子 当有多个 IO 密集型的任务要被处理时,我们自然而然会想到多线程.但如果任务非常多,我们不可能每一个任务都启动一个线程去处理,这个时候最好的办法就是实现一个线程池,至于池子里面的线程数量可以根据业务场景进行设置. 比如我们实现一个有 10

  • Java实现手写一个线程池的示例代码

    目录 概述 线程池框架设计 代码实现 阻塞队列的实现 线程池消费端实现 获取任务超时设计 拒绝策略设计 概述 线程池技术想必大家都不陌生把,相信在平时的工作中没有少用,而且这也是面试频率非常高的一个知识点,那么大家知道它的实现原理和细节吗?如果直接去看jdk源码的话,可能有一定的难度,那么我们可以先通过手写一个简单的线程池框架,去掌握线程池的基本原理后,再去看jdk的线程池源码就会相对容易,而且不容易忘记. 线程池框架设计 我们都知道,线程资源的创建和销毁并不是没有代价的,甚至开销是非常高的.同

  • C++实现一个简单的线程池的示例代码

    目录 一.设计 二.参数选择 三.类设计 一.设计 线程池应该包括 保存线程的容器,保存任务的容器. 为了能保证避免线程对任务的竞态获取,需要对任务队列进行加锁. 为了使得工作线程感知任务的到来,需要使用条件变量来唤醒工作线程. 任务容器中的任务管理. 任务的处理API. 二.参数选择 使用数组存放线程,链表存放任务. 三.类设计 线程池类 template<typename T> class threadpool { public: threadpool(int thread_num,int

  • Java实现手写线程池的示例代码

    目录 前言 线程池给我们提供的功能 工具介绍 Worker设计 线程池设计 总结 前言 在我们的日常的编程当中,并发是始终离不开的主题,而在并发多线程当中,线程池又是一个不可规避的问题.多线程可以提高我们并发程序的效率,可以让我们不去频繁的申请和释放线程,这是一个很大的花销,而在线程池当中就不需要去频繁的申请线程,他的主要原理是申请完线程之后并不中断,而是不断的去队列当中领取任务,然后执行,反复这样的操作.在本篇文章当中我们主要是介绍线程池的原理,因此我们会自己写一个非常非常简单的线程池,主要帮

  • Java实现手写乞丐版线程池的示例代码

    目录 前言 线程池的具体实现 线程池实现思路 线程池实现代码 线程池测试代码 杂谈 总结 前言 在上篇文章线程池的前世今生当中我们介绍了实现线程池的原理,在这篇文章当中我们主要介绍实现一个非常简易版的线程池,深入的去理解其中的原理,麻雀虽小,五脏俱全. 线程池的具体实现 线程池实现思路 任务保存到哪里? 在上篇文章线程池的前世今生当中我们具体去介绍了线程池当中的原理.在线程池当中我们有很多个线程不断的从任务池(用户在使用线程池的时候不断的使用execute方法将任务添加到线程池当中)里面去拿任务

  • Android线程池控制并发数多线程下载

    多线程下载并不是并发下载线程越多越好,因为当用户开启太多的并发线程之后,应用程序需要维护每条线程的开销,线程同步的开销. 这些开销反而会导致下载速度降低.因此需要避免在代码中直接开启大量线程执行下载. 主要实现步奏: 1.定义一个DownUtil类,下载工作基本在此类完成,在构造器中初始化UI线程的Handler.用于子线程和UI线程传递下载进度值. 2.所有的下载任务都保存在LinkedList.在init()方法中开启一个后台线程,不断地从LinkedList中取任务交给线程池中的空闲线程执

随机推荐

其他