Overview
1. ThreadPoolExecutor provides basic implementation for external purposes as a package, and provides external services such as management task execution, thread scheduling, thread pool management, etc. in the form of an internal thread pool;
2. The thread services provided by the Executors method all implement different thread pooling mechanisms through parameter settings.
3. First understand the mechanism of thread pool management, which will help to use it correctly and avoid serious failures caused by incorrect use. At the same time, you can implement your own thread pool according to your needs
ThreadPoolExecutor class
Construction method
public ThreadPoolExecutor( int corePoolSize, //Number of core threads: If the number of currently running threads does not reach corePoolSize, create a new thread, otherwise it will be added to the task queue int maximumPoolSize, //Maximum number of threads: the maximum number of threads existing in the current system long keepAliveTime, //Maximum idle time: the maximum time when the thread is idle. If the time exceeds the time, the thread will be destroyed; set allowCodeThreadTimeOut (true/false) to control whether the core thread is destroyed. The default false means that the core thread will not be destroyed even if it exceeds the maximum thread time. TimeUnit unit, //Time unit: The maximum time for thread idle BlockingQueue<Runnable> workQueue, //Task queue: After the number of core threads is full, the submitted task is added to the queue, and the number of core threads is reduced before creating threads; when the task queue is full but the maximum number of threads has not reached, a new non-core thread is created ThreadFactory threadFactory, //Thread factory: Creation of custom threads RejectedExecutionHandler handler //Saturation processing mechanism: Measures taken when the task queue is full and the maximum number of threads is reached,)
Thread pool principle
The thread pool bottom layer uses the blocked queue BlockingQueue **.
Queues follow: first-in, first-out, and later-out. The difference between blocking queues (BlockingQueue) and non-blocking queues (ConcurrentLinkedQueue):
Unbounded and bounded queues:
ConcurrentLinkedQueue is an unbounded queue, and you don’t need to set the length, and you can store the value at will (in fact, it is forged by jdk, and the maximum length is the maximum value of Integer). BlockingQueue is a bounded queue, and you need to set the length. Note: If BlockingQueue does not set the waiting time, it is a non-blocking queue.
Deposit:
Non-blocking queues: If the storage exceeds the total number of queues and cannot be added, it will be lost. Blocking queue: If the total number of queues is stored exceeds the total number, wait until the queue is decoupled, or the waiting time is set)
Get:
Non-blocking queue: Returns empty if empty. Blocking queue: If empty, wait until a new queue is included in the column or the set waiting time is exceeded
How to create a thread pool
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
- ThreadPoolExecutor
- Parameter description
- Core thread size (corePoolSize)
- Maximum thread size (maximumPoolSize)
- Termination time (keepAliveTime)
- Unit timeout
- workQueue thread container
Custom thread pool
1. Write task categories
public class MyTask implements Runnable{ //Task id private int id; public MyTask(int id){ =id; } @Override public void run() { String name=().getName(); ("Thread:"+name+"-->Tasks to be executed soon"+id); try { (200); } catch (InterruptedException e) { (); } ("Thread:"+name+"Execution Completed"+id); } @Override public String toString() { return "MyTask{" + "codeview">public class MyThread extends Thread{ private List<Runnable> tasks; public MyThread(String name, List<Runnable> tasks){ super(name); =tasks; } @Override public void run() { while (() > 0){ Runnable r= (0); (); } } }
3. Write thread pool classes to manage thread execution
public class MyThreadPool { private List<Runnable> tasks = (new LinkedList<>()); /** * Current number of threads */ private int num; /** * Number of core threads */ private int corePoolSize; /** * Maximum number of threads */ private int maxSize; /** * Number of task queues */ private int workSize; public MyThreadPool(int corePoolSize, int maxSize, int workSize) { = corePoolSize; = maxSize; = workSize; } /** * Submit a task */ public void submit(Runnable r){ if (()>=workSize && () > maxSize){ ("Task:"+r+"Discarded"); }else{ (r); execTask(r); } } public void execTask(Runnable r){ if (corePoolSize > num){ new MyThread("Core Thread:"+num,tasks).start(); num++; }else if(num < maxSize){ new MyThread("Non-core thread:"+num,tasks).start(); num++; }else{ ("Task:"+r+"Cached"); } } }
4. Test
public class Demo { public static void main(String[] args) { MyThreadPool myThreadPool = new MyThreadPool(2, 4, 20); for (int i =0;i< 300;i++){ MyTask myTask = new MyTask(i); (myTask); } } }
The above is the ThreadPoolExecutor and custom thread pool in Android development;
At the end of the article
1. Use ThreadPoolExecutor to customize the thread pool. It depends on the purpose of the thread. If the task volume is not large, you can use an unbounded queue. If the task volume is very large, use a bounded queue to prevent OOM.
2. If the task volume is large, each task is required to be processed successfully. The submitted task must be blocked and the rejection mechanism must be rewrited and the blocked submission will be changed. Ensure that no task is abandoned
3. The maximum number of threads is generally set to 2N+1, and N is the number of CPU cores.
4. The number of core threads depends on the application. If it is a task, run once a day and set to 0. It is appropriate, because it is stopped after running. If it is a common thread pool, it depends on the number of tasks. Should one core or several core threads be retained
5. If you want to get the task execution results, use CompletionService. However, please note that if you get the task results, you must reopen a thread to obtain it. If you get it in the main thread, you have to wait until the task is submitted before obtaining it, which will block a large number of task results and the queue is too large OOM, so it is best to open a thread asynchronously to obtain the results.
The above is the detailed explanation of Android development ThreadPoolExecutor and custom thread pool. For more information about Android ThreadPoolExecutor, please follow my other related articles!