SoFunction
Updated on 2025-03-11

A brief discussion on the management of thread pools in Android

When it comes to threads, we need to talk about the thread mechanism. Handler, Looper, MessageQueue can be said to be three mountains.

Handler

Handler is actually a handler, or a sender, which will send the message to the message queue, that is, Looper, and then perform the operation of fetching the message in an infinite loop queue (mMessage); This sentence means that I have finished processing the operation and I have sent it! Then process it in the place where I accept it! Is it simple to understand?

How do we usually do asynchronous operations in projects?

// Open a child thread here for time-consuming operations new Thread() {
  @Override
  public void run() {
   .......
   Message mMessage = new Message();
    = 1;
   //Send it to the message queue here   (mMessage);
   }
  }.start();
 /**
   * This is the place to deal with it
   */
 class MyHandler extends Handler{
  @Override
  public void handleMessage(Message msg) {
   (msg);
   switch (){
   //Fetch out the corresponding message for processing    ........
   }
  }
 }

So where is our message queue started? Follow the source code to take a look

# 
public static void main(String[] args) {
  //Omit the code.  .  .  .  .  
  //A message queue was created here!  ();

  ActivityThread thread = new ActivityThread();
  (false);

  if (sMainThreadHandler == null) {
   sMainThreadHandler = ();
  }

  //I don't understand this sentence, isn't it impossible to execute it all the time  if (false) {
   ().setMessageLogging(new
     LogPrinter(, "ActivityThread"));
  }

  (Trace.TRACE_TAG_ACTIVITY_MANAGER);
  //The message queue is running!  ();

  throw new RuntimeException("Main thread loop unexpectedly exited");
 }
public Handler(Callback callback, boolean async) {
  mLooper = ();
  // Pay attention to the exception thrown here. If mLooper==null  if (mLooper == null) {
   throw new RuntimeException(
    "Can't create handler inside thread that has not called ()");
  }
  //Get message queue  mQueue = ;
  mCallback = callback;
  mAsynchronous = async;
 }

The above operation of the Android system obtains and starts a message queue. Too much source code is not to be described here, and it will not take up a lot of space.

Here is a common question for the trial below, which is whether you can create a Handler in a child thread. It is actually OK, but who can use it like this - -

new Thread() {
  Handler mHandler = null;
  @Override
  public void run() {
   //Get here   ();
   mHandler = new Handler();
   //Start here   ();
  }
 }.start();

Multithreaded creation

Generally, when we start a thread during development, we will do it directly.

new Thread() {
   @Override
   public void run() {
    doing.....
   }
  }.start();
new Thread(new Runnable() {
   @Override
   public void run() {
    doing.....
   }
  }).start();

Note that one passes the Runnable object, the other does not, but what is the difference between these two, why do you need to derive two?

I won’t look at the source code here, let’s briefly describe it. In fact, Thread is a package implementation class for Runnabled. Runnable has only one method, which is run(). I have thought about it before. Why is Runnable only one method? I found an answer in a conversation later. Maybe it’s because of the expansion. Maybe the JAVA language wants to expand some other things, so I will write it directly in Runnable in the future. Otherwise, I didn't think of another answer why I had to pass a Runnable, maybe just like the baseActivity we developed

Common operation methods for threads

  1. wait() When a thread executes wait(), it will enter a waiting pool related to the object, and at the same time it loses the machine to release the current object, so that other threads can access it, that is, other threads can call notify() to wake up.
  2. sleep() calls the thread to enter a sleep state. It cannot change the object's machine lock and other threads cannot access it.
  3. Join() just wait for yourself to finish
  4. yidld, you're anxious, come first

This is actually the simple vernacular narrative. I hope I can take a look at the demo and understand it.

Some other methods, Callable, Future, FutureTask

Runnable is an extension interface for thread management and cannot be used in thread pools, so you must have a method to manage in thread pools. So Callable, Future, FutureTask is an interface for opening threads in thread pools.

Future defines the standard interface, such as get(), isDone(), isCancelled()... FutureTask is his implementation class. Here I briefly talk about its usage.

/**
  * ================================================================
  * Author: Xia Muyao Github address: /XiaMuYaoDQX
  * Version: 1.0
  * Created date: 2018/1/10
  * describe:
  * Revised history:
  * ================================================================
  */
class FutureDemo {
 //Create a singleton thread static ExecutorService mExecutor = ();

 public static void main(String[] args) throws ExecutionException, InterruptedException {
  ftureWithRunnable();
  ftureWithCallable();
  ftureTask();
 }

 /**
   * No return value is specified, so the return is null, and the Runnable submitted to the thread pool is
   *
   * @throws ExecutionException
   * @throws InterruptedException
   */
 private static void ftureWithRunnable() throws ExecutionException, InterruptedException {
  Future<?> result1 = (new Runnable() {
   @Override
   public void run() {
    fibc(20);
    (().getName());
   }
  });
  ("Runnable" + ());
 }

 /**
   * Callable is submitted, with a return value, and the blocking thread can get the value obtained
   *
   * @throws ExecutionException
   * @throws InterruptedException
   */
 private static void ftureWithCallable() throws ExecutionException, InterruptedException {
  Future<Integer> result2 = (new Callable<Integer>() {
   @Override
   public Integer call() throws Exception {
    (().getName());
    return fibc(20);
   }
  });
  ("Callable" + ());
 }

 /**
   * Submitted futureTask object
   * @throws ExecutionException
   * @throws InterruptedException
   */
 private static void ftureTask() throws ExecutionException, InterruptedException {
  FutureTask<Integer> futureTask = new FutureTask<Integer>(new Callable<Integer>() {
   @Override
   public Integer call() throws Exception {
    (().getName());
    return fibc(20);
   }
  });
  (futureTask);
  ("futureTask" + ());

 }

 private static int fibc(int num) {
  if (num == 0) {
   return 0;
  }
  if (num == 1) {
   return 1;
  }
  return fibc(num - 1) + fibc(num - 2);
 }
}

Thread pool

Java provides thread pools through Executors, which are:

  1. newCachedThreadPool creates a cacheable thread pool. If the thread pool length exceeds the processing needs, it can flexibly recycle idle threads. If there is no recycle, create a new thread.
  2. newFixedThreadPool Creates a fixed-length thread pool that can control the maximum number of threads concurrency, and the excess threads will wait in the queue.
  3. newScheduledThreadPool Creates a fixed-length thread pool that supports timed and periodic task execution.
  4. newSingleThreadExecutor Creates a single-threaded thread pool, which will only use a unique worker thread to execute tasks, ensuring that all tasks are executed in the specified order (FIFO, LIFO, priority).

Sample code

newCachedThreadPool

Create a cacheable thread pool. If the thread pool length exceeds the processing needs, you can flexibly recycle idle threads. If there is no recycle, create a new thread. The sample code is as follows:

public class ThreadPoolExecutorTest { 
 public static void main(String[] args) { 
 ExecutorService cachedThreadPool = (); 
 for (int i = 0; i < 10; i++) { 
 final int index = i; 
 try { 
 (index * 1000); 
 } catch (InterruptedException e) { 
 (); 
 } 
 (new Runnable() { 
 public void run() { 
  (index); 
 } 
 }); 
 } 
 } 
} 

The thread pool is infinite. When the second task is executed, the first task has been completed, and the thread that executes the first task will be reused without creating a new thread every time.

newFixedThreadPool

Create a fixed-length thread pool that can control the maximum number of threads concurrency, and the excess threads will wait in the queue. The sample code is as follows:

public class ThreadPoolExecutorTest { 
 public static void main(String[] args) { 
 ExecutorService fixedThreadPool = (3); 
 for (int i = 0; i < 10; i++) { 
 final int index = i; 
 (new Runnable() { 
 public void run() { 
  try { 
  (index); 
  (2000); 
  } catch (InterruptedException e) { 
  (); 
  } 
 } 
 }); 
 } 
 } 
} 

Because the thread pool size is 3, sleep 2 seconds after each task outputs index, so 3 numbers are printed every two seconds.

The size of a fixed-length thread pool is best set according to the system resources. Such as ().availableProcessors()

newScheduledThreadPool

Create a fixed-length thread pool that supports timed and periodic task execution. The sample code for delayed execution is as follows:

public class ThreadPoolExecutorTest { 
 public static void main(String[] args) { 
 ScheduledExecutorService scheduledThreadPool = (5); 
 (new Runnable() { 
 public void run() { 
 ("delay 3 seconds"); 
 } 
 }, 3, ); 
 } 
} 

Indicates delay execution by 3 seconds.

The sample code is executed regularly as follows:

public class ThreadPoolExecutorTest { 
 public static void main(String[] args) { 
 ScheduledExecutorService scheduledThreadPool = (5); 
 (new Runnable() { 
 public void run() { 
 ("delay 1 seconds, and excute every 3 seconds"); 
 } 
 }, 1, 3, ); 
 } 
} 

It means that the delay is performed every 3 seconds after 1 second.

newSingleThreadExecutor

public class ThreadPoolExecutorTest { 
 public static void main(String[] args) { 
 ExecutorService singleThreadExecutor = (); 
 for (int i = 0; i < 10; i++) { 
 final int index = i; 
 (new Runnable() { 
 public void run() { 
  try { 
  (index); 
  (2000); 
  } catch (InterruptedException e) { 
  (); 
  } 
 } 
 }); 
 } 
 } 
}

Here I will briefly describe various methods of thread management, and will explain it in the future.

The above is all the content of this article. I hope it will be helpful to everyone's study and I hope everyone will support me more.