Run the code task instance in the Android thread pool

  • 2020-06-01 11:01:06
  • OfStack

This section shows how to perform tasks in a thread pool. The process is to add a task to the work queue of the thread pool, and when a thread becomes available (after executing other tasks, idle, or not yet executing a task),ThreadPoolExecutor will fetch the task from the queue and run it in the thread.
This lesson also shows you how to stop a running task.

Performs tasks on threads in the thread pool

The Runnable object is passed in ThreadPoolExecutor.execute () to start the task. This method adds tasks to the thread pool work queue. When a thread is free, the manager pulls out the task that has been waiting the longest and runs it on the thread.


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 Runnable, the run() method is automatically called.

Interrupts running code

To stop a task, you need to interrupt the progress of the task. You need to save the handle of the current thread while creating the task.
Such as:


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 the thread, call Thread.interrupt (). Tip: thread objects are system-controlled and can be edited outside of your app process. For this reason, you need to put an access lock in a synchronized block before breaking it:


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 the waiting thread, but does not interrupt the cpu or network-intensive tasks. To prevent the system from slowing down, you should test the request waiting for an interrupt before attempting the operation.


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


Related articles: