This is the 10th day of my participation in Gwen Challenge

This article is based onAndroid 9.0.0The source code

framework/base/core/java/andorid/os/AsyncTask.java
Copy the code

Introduction to the

IntentService: IntentService: IntentService: IntentService: IntentService: IntentService: IntentService: IntentService: IntentService: IntentService: IntentService: IntentService: IntentService: IntentService: IntentService: IntentService: IntentService: IntentService: IntentService: IntentService: IntentService: IntentService: IntentService They are similar in that they can execute time-consuming tasks in a new thread without blocking the main thread. The difference is that AsyncTask can track the execution process and results of tasks and display them in the main thread.

Knowledge reserves

LinkedBlockingQueue Blocks the queue

BlockingQueue is widely used in producer-consumer problems because BlockingQueue provides blocking methods for insertion and removal. When the queue container is full, the producer thread blocks until the queue is full. When the queue container is empty, the consumer thread is blocked until the queue is not empty. The LinkedBlockingQueue class implements the BlockingQueue interface. LinkedBlockingQueue stores its elements internally in a chained structure (linked nodes). The chain structure can select an upper limit if desired. If no upper limit is defined, integer.max_value is used as the upper limit. LinkedBlockingQueue internally stores elements in FIFO(first in, first out) order. The first element in the queue is the oldest of all elements, and the last element is the shortest.

ArrayDeque

Array queue features of ArrayDeque

  • A queue that grows in size
  • Internally, arrays are used to store data
  • Thread insecurity
  • The internal array length is 8, 16, 32… . Two to the n
  • The head pointer starts at the end of the internal array, and the tail pointer starts at 0. Head is subtracted by one when the head is inserted, and tail is incremented by one when the tail is inserted. If head==tail, the array capacity is insufficient. In this case, the array capacity needs to be doubled.

ExecutorService Executive service

Java. Util. Concurrent. The ExecutorService interface represents an asynchronous execution mechanism, enabled us to perform a task in the background. So an ExecutorService is a lot like a thread pool.

ExecutorService simple implementation

ExecutorService executorService = Executors.newFixedThreadPool(10);  

executorService.execute(new Runnable() {  
    public void run(a) {  
        System.out.println("Asynchronous task"); }}); executorService.shutdown();Copy the code

Start by creating an ExecutorService using the newFixedThreadPool() factory method. A pool of ten threads is created to perform tasks. An anonymous implementation class of the Runnable interface is then passed to the execute() method. This will cause a thread within the ExecutorService to execute the Runnable.

ThreadPoolExecutor ThreadPoolExecutor

Ava. Util. Concurrent ThreadPoolExecutor is an implementation of the ExecutorService interface. ThreadPoolExecutor uses threads from its internal pool to perform a given task (Callable or Runnable).

Construction method:

// constructor
public ThreadPoolExecutor(int corePoolSize,
                          int maximumPoolSize,
                          long keepAliveTime,
                          TimeUnit unit,
                          BlockingQueue<Runnable> workQueue,
                          ThreadFactory threadFactory,
                          RejectedExecutionHandler handler) {
    if (corePoolSize < 0 ||
        maximumPoolSize <= 0 ||
        maximumPoolSize < corePoolSize ||
        keepAliveTime < 0)
        throw new IllegalArgumentException();
    if (workQueue == null || threadFactory == null || handler == null)
        throw new NullPointerException();
    this.corePoolSize = corePoolSize;
    this.maximumPoolSize = maximumPoolSize;
    this.workQueue = workQueue;
    this.keepAliveTime = unit.toNanos(keepAliveTime);
    this.threadFactory = threadFactory;
    this.handler = handler;
}
Copy the code

Let’s look at the meanings and functions of several parameters

  • CorePoolSize – Number of core threads, that is, the number of threads allowed to be idle
  • MaximumPoolSize – The maximum number of threads, the capacity of this thread pool
  • KeepAliveTime – The idle lifetime of a non-core thread
  • Unit – The unit of the previous argument
  • WorkQueue – Task queue (blocking queue)
  • ThreadFacotry – Thread creation factory
  • Handler – Reject when the thread pool or task queue capacity is full

Callable&&Future

public interface Callable<V> {
    /**
     * Computes a result, or throws an exception if unable to do so.
     *
     * @return computed result
     * @throws Exception if unable to compute a result
     */
    V call(a) throws Exception;
}
Copy the code
public interface Runnable {
    /**
     * When an object implementing interface <code>Runnable</code> is used
     * to create a thread, starting the thread causes the object's
     * <code>run</code> method to be called in that separately executing
     * thread.
     * <p>
     * The general contract of the method <code>run</code> is that it may
     * take any action whatsoever.
     *
     * @see     java.lang.Thread#run()
     */
    public abstract void run(a);
}
Copy the code

Simply put, the Callable interface is equivalent to Runable, and call() is equivalent to run(), except that it returns a value. We can call the Callable from the ExecutorService, which returns a Future object, such as: Future

future = Executors.newSingleThreadExecutor().submit(mCallable);

 
public interface Future<V> {

  boolean cancel(boolean mayInterruptIfRunning);

  boolean isCancelled(a);

  boolean isDone(a);
  
  V get(a) throws InterruptedException, ExecutionException;
  
  V get(long timeout, TimeUnit unit)
      throws InterruptedException, ExecutionException, TimeoutException;
}
Copy the code

The Future interface focuses on two methods: Cancel (Boolean mayInterruptIfRunning), which terminates the thread, and get(), which blocks the thread until the Callable call() returns an object as its return value. MayInterruptIfRunning is a Boolean value that you can read in the FutureTask source code. It simply adds thread.interrupt() logic. In combination with the Callable code, the Future is used as follows:

Future<String> future = Executors.newSingleThreadExecutor().submit(mCallable);
// Block the thread waiting for callable.call () to return
String result = future.get();
Copy the code

FutureTask

public class FutureTask<V> implements RunnableFuture<V>

public interface RunnableFuture<V> extends Runnable.Future<V> {  
    /** * Sets this Future to the result of its computation * unless it has been cancelled. */  
    void run(a); } ` ` `Copy the code

FutureTask is both a Runable and a Future by inheritance, so we can use it as a Runable, but it also has the ability to terminate a thread, block a thread, wait for a Callable to execute, and get a return value. Also note that its constructor is public FutureTask(Callable Callable), so a Callable object is required as a parameter when instantiating FutureTask.