• Running Code on a Thread Pool Thread_翻译


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

      

  • 相关阅读:
    C#中抽象类和接口的区别
    人机交互复习
    信息安全复习2关于网络安全
    多读书
    致大学:我的最后几次坚持
    腾讯CMEM平台简介
    面向对象中组合和继承的关系
    软件测试笔记
    一个人的独白(两年生活的自省)
    学习之路二十四:2012年我从工作中学会了哪些?
  • 原文地址:https://www.cnblogs.com/itblog/p/2945043.html
Copyright © 2020-2023  润新知