What is a thread
A thread, sometimes called a lightweight process, is the smallest unit of a program’s execution flow. A standard thread by thread ID of the current instruction pointer, register set and stack, is an entity in the process, is the basic unit of the system independent scheduling and dispatching, the thread does not have the system resources, with only a little in operation of essential resources, but it can be to belong to a Shared other threads of a process possesses all the resources. One thread can create and undo another thread, and multiple threads in the same process can execute concurrently. Every program has at least one thread. If the program has only one thread, that’s the program itself.
A thread is a single sequence control flow in a program. Process has a relatively independent, schedulable execution unit, is the system independent scheduling and dispatching CPU basic unit instruction run program scheduling unit.
Thread state
Threads also have three basic states: ready, blocked, and running.
-
Ready state refers to the thread has all the conditions to run, logically can run, waiting for the processor;
-
The running state is when the thread owns the processor and is running;
-
A blocked state is when a thread is waiting for an event (such as a semaphore) that cannot be logically executed.
Thread state graph
Memory and threads
Increasing the number of concurrent threads causes an increase in memory consumption, and it is important to strike a balance between the two. We know that multi-threading concurrent access to the same memory area can cause many problems, such as read and write permissions contention, ABA problems, etc., so we need to introduce the concept of locking.
Threads in Android
purpose
Perform some time-consuming, easily blocked transactions to prevent the main thread from blocking and causing irreversible exceptions.
The core number
The number of cores in the thread pool is calculated based on the number of CPU cores on the device. In terms of performance optimization, it is necessary to ensure that the number of threads does not fluctuate wildly (threads consume performance).
Looper, Handler, MessageQueue, Message
Android provides a thread design model for Looper, Handler, MessageQueue, and Message. Looper: Keeps the thread alive and constantly fetching tasks from the task queue. MessageQueue: Uses Message, Runnable as the carrier of the task to be passed between different threads. Message: task carrier. Handler: Helps manage queue tasks. It not only inserts tasks to the head and tail of the queue, but also ensures that tasks are removed from the queue in time to be cancelled.
Android Multithreading solution
AsyncTask: Provides a simple and convenient mechanism for fast switching between UI threads and worker threads.
ExecuteOnExecutor: To execute an asynchronous task, we need to call this method in our code to trigger the execution of the asynchronous task. OnPreExecute: Executed immediately after executeOnExecutor is invoked. It is used to mark the UI before executing background tasks. DoInBackground: Executed immediately after onPreExecute completes and is used to perform time-consuming operations. This method receives input parameters and returns computed results. You can call publishProgress during execution to update progress information. OnProgressUpdate: This method is executed when publishProgress is called to update progress information directly to the UI component. OnPostExecute: This method will be called when the background operation is finished, and the calculation result will be passed to this method as a parameter, directly displaying the result on the UI component.
As can be seen from the figure, AsyncTask provides Android developers with a convenient solution for communication between the main thread and child threads. By processing time-consuming and easily blocking transactions in the child thread, the result of processing by the child thread is passed to the Handler of the main thread for processing by Message.
Of course AsyncTask can also provide a solution (rarely used in real development) for communication between two different child threads, i.e. a custom Looper Handler. In this case, OnPreExecute, onProgressUpdate, and onPostExecute cannot perform tasks that the main thread can only perform, such as interface refresh.
HandlerThread: Sets up a dedicated thread for callback methods or waiting for tasks to execute, and provides a scheduling mechanism for thread tasks.
HandlerThread is a Thread with a Looper (execute Looper and loop() in run()), set the Looper to a Handler, and use the Handler to process transactions. The Looper in this Handler is a non-mainline Looper, so it cannot handle operations that can only be handled on the mainline, such as interface refreshes. See Handler and Looper diagram for details.
ThreadPool: Divide tasks into units and distribute them to different threads for concurrent processing.
A thread pool, as its name implies, is a thread-managed wait pool. It can customize the number of threads in the pool, the maximum wait time of a thread (thread alive time), and the task queue and order.
IntentService: suitable for executing background Service tasks triggered by the UI and reporting the background task execution status to the UI through a certain mechanism.
IntentService is a combination of Service and HandlerThread. It inherits all the features of Service and HandlerThread and needs to implement the onHandleIntent method, which is executed on a child thread.
WorkManager
This is a new architecture set up at this year’s I/O conference — managing tasks that need to work in the background — to ensure that tasks can be executed even if your application isn’t started.
Frequently Asked Questions (code in screenshot is for example only)
Common threading problems have the following aspects:
1. Shared data synchronization
The execution between threads is out of order, and locks are needed to ensure the integrity of the same shared data.
2. Memory leakage
This can result in Handler leaks, Timer leaks (there are no cancels after completion), thread pool leaks (there are more transactions waiting in the thread pool and the waiting Runnable holds objects that need to be released), and so on
Handler leak
The Timer leak
3. After the asynchronous data result is returned, the interface is not initialized or destroyed.The asynchronous result does not return until the Activity destroys, and mTv is NULL
4, unreasonable thread creation (pool) leads to a large amount of memory consumption, resulting in the main thread competition CPU pressure.
Creating a thread is a performance-consuming, resource-consuming operation, with approximately 64KB of memory consumed per thread.
Unreasonable create thread (pool)
To optimize the
Define a global ThreadMananger management class that manages the operations of new threads through a global Thread pool. 2. When defining a thread pool, use a final static structure to define the pool so that the class or method is not called repeatedly ina short period of time, resulting in an increase in threads. 3, with the nature of the Timer thread (HandlerThread, Timer), must exit or cancel operations (to prevent memory leakage), as far as possible to replace the Timer HandlerThread. 4. App implements a thread pool corresponding to its business (e.g. with priority).
conclusion
Thread it is like a double-edged sword, with the good time can bring us get twice the result with half the effort effect, such as using bad will bring us trouble, and this pain is not a half will be able to get rid of (because when found the problem, is often the need to optimize period, all the business with each other), so at the beginning of the project requires strict consider consider these issues.