[Switch] thread pool introduction under JUC, juc Thread Pool
IntroductionDisadvantages andJavaUse of four thread poolsWhich is also applicable to Android. This article is a basic article. Later I will share some advanced features of the thread pool.
1. disadvantages of new Thread
Do you still have the following new Thread to execute an asynchronous task?
new Thread(new Runnable() { @Overridepublic void run() {// TODO Auto-generated method stub}}).start();
You have too many threads. the disadvantages of new Thread are as follows:
A. The performance of each new object created by the new Thread is poor.
B. There is a lack of unified management of threads, and there may be no restrictions on the creation of new threads, competition between them, and the possibility of occupying too much system resources, resulting in crashes or oom.
C. Lack of more functions, such as scheduled execution, regular execution, and thread interruption.
Compared with new Thread, Java provides the following four Thread pools:
A. reuse existing threads to reduce the overhead of object creation and elimination, and improve performance.
B. It can effectively control the maximum number of concurrent threads, improve the usage of system resources, and avoid excessive resource competition and congestion.
C. provides scheduled execution, regular execution, single thread, concurrency control, and other functions.
2. Java Thread Pool
Java provides four thread pools through Executors:
NewCachedThreadPool creates a cache thread pool. If the thread pool length exceeds the processing requirement, Idle threads can be recycled flexibly. If no thread pool length exists, a new thread is created.
NewFixedThreadPool creates a fixed-length thread pool, which can control the maximum number of concurrent threads. threads that exceed the limit will wait in the queue.
NewScheduledThreadPool creates a fixed-length thread pool that supports scheduled and periodic task execution.
NewSingleThreadExecutor creates a single-threaded thread pool. It only uses a unique worker thread to execute tasks, ensuring that all tasks are executed in the specified Order (FIFO, LIFO, priority.
(1). newCachedThreadPool
Create a cache thread pool. If the thread pool length exceeds the processing requirement, free threads can be recycled flexibly. If no thread pool can be recycled, a new thread is created. The sample code is as follows:
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();for (int i = 0; i < 10; i++) {final int index = i;try {Thread.sleep(index * 1000);} catch (InterruptedException e) {e.printStackTrace();} cachedThreadPool.execute(new Runnable() { @Overridepublic void run() {System.out.println(index);}});}
The thread pool is infinite. When the second task is executed and the first task is completed, the thread for executing the first task is reused instead of creating a new thread each time.
(2). newFixedThreadPool
Create a fixed-length thread pool to control the maximum number of concurrent threads. threads that exceed the limit will wait in the queue. The sample code is as follows:
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);for (int i = 0; i < 10; i++) {final int index = i;fixedThreadPool.execute(new Runnable() { @Overridepublic void run() {try {System.out.println(index);Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}});}
Because the thread pool size is 3 and each task outputs an index and sleep for 2 seconds, three numbers are printed every two seconds.
It is best to set the size of the fixed-length thread pool based on system resources. For example, Runtime. getRuntime (). availableProcessors (). See PreloadDataCache.
(3) newScheduledThreadPool
Creates a fixed-length thread pool that supports scheduled and periodic task execution. Example code of delayed execution:
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);scheduledThreadPool.schedule(new Runnable() { @Overridepublic void run() {System.out.println("delay 3 seconds");}}, 3, TimeUnit.SECONDS);
The execution is delayed by 3 seconds.
Periodically execute the following sample code:
scheduledThreadPool.scheduleAtFixedRate(new Runnable() { @Overridepublic void run() {System.out.println("delay 1 seconds, and excute every 3 seconds");}}, 1, 3, TimeUnit.SECONDS);
It indicates that the task is executed every 3 seconds after a delay of 1 second.
ScheduledExecutorService is safer and more powerful than Timer, and will be compared separately later.
(4) newSingleThreadExecutor
Create a single-threaded thread pool. It only uses a unique worker thread to execute tasks and ensures that all tasks are executed in the specified order (FIFO, LIFO, priority. The sample code is as follows:
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();for (int i = 0; i < 10; i++) {final int index = i;singleThreadExecutor.execute(new Runnable() { @Overridepublic void run() {try {System.out.println(index);Thread.sleep(2000);} catch (InterruptedException e) {// TODO Auto-generated catch blocke.printStackTrace();}}});}
The results are output in sequence, which is equivalent to executing each task in sequence.
Currently, most GUI programs are single-threaded. A single thread in Android can be used for operations such as database operations, file operations, batch installation of applications, batch deletion of applications, and other operations that are not suitable for merging and sending but may be IO obstructive and affect the UI thread response.
The role of the thread pool:
The thread pool is used to limit the number of execution threads in the system.
Based on the environment of the system, you can automatically or manually set the number of threads to achieve the best running effect. This reduces the waste of system resources and causes low system congestion efficiency. Use the thread pool to control the number of threads and wait for other threads. After a task is executed, the task starts from the top of the queue. If no process is waiting in the queue, this resource in the thread pool is waiting. When a new task needs to run, if there is a waiting working thread in the thread pool, it can start to run; otherwise, it enters the waiting queue.
Why thread pool:
1. reduces the number of threads created and destroyed. Each worker thread can be reused to execute multiple tasks.
2. you can adjust the number of worker threads in the thread pool according to the system's capacity to prevent servers from getting tired due to excessive memory consumption (each thread requires about 1 MB of memory, the more threads open, the larger the memory consumed, and the machine crashes ).
The top-level interface of the thread pool in Java is Executor, but in a strict sense, Executor is not a thread pool, but a tool for executing the thread. The real thread pool interface is ExecutorService.
Important classes:
ExecutorService |
Real thread pool interface. |
ScheduledExecutorService |
It can be similar to Timer/TimerTask to solve the problem of repeated task execution. |
ThreadPoolExecutor |
ExecutorService default implementation. |
ScheduledThreadPoolExecutor |
Inherits the implementation of the ScheduledExecutorService interface of ThreadPoolExecutor and class implementation of periodic task scheduling. |
It is complicated to configure a thread pool, especially when the thread pool principle is not clear, it is very likely that the thread pool configured is not optimal, therefore, some static factories are provided in the Executors class to generate some common thread pools.
1. newSingleThreadExecutor
Creates a single-threaded thread pool. This thread pool only has one thread working, which is equivalent to a single thread serial execution of all tasks. If this unique thread ends due to an exception, a new thread will replace it. This thread pool ensures that all tasks are executed in the order they are submitted.
2.NewFixedThreadPool
Create a fixed thread pool. Each time a task is submitted, a thread is created until the thread reaches the maximum size of the thread pool. The size of the thread pool remains unchanged once it reaches the maximum value. If a thread ends due to an execution exception, the thread pool will add a new thread.
3. newCachedThreadPool
Create a cacheable thread pool. If the thread pool size exceeds the thread required for processing the task,
Then, some Idle threads (which do not execute tasks in 60 seconds) will be reclaimed. When the number of tasks increases, the thread pool can intelligently add new threads to process the tasks. This thread pool does not limit the thread pool size. The thread pool size depends entirely on the maximum thread size that can be created by the operating system (or JVM.
4.NewScheduledThreadPool
Creates an infinite thread pool. This thread pool supports regular and periodic task execution requirements.
Instance
1: newSingleThreadExecutor ·
MyThread. java
Public class MyThread extends Thread {@ Override public void run () {System. out. println (Thread. currentThread (). getName () + "is being executed... ");}}
TestSingleThreadExecutor. java
Public class TestSingleThreadExecutor {public static void main (String [] args) {// create a thread pool that can reuse a fixed number of threads ExecutorService pool = Executors. newSingleThreadExecutor (); // creates and implements the Runnable interface object. Of course, the Thread object also implements the Runnable interface Thread t1 = new MyThread (); Thread t2 = new MyThread (); thread t3 = new MyThread (); Thread t4 = new MyThread (); Thread t5 = new MyThread (); // put the Thread into the pool and execute pool.exe cute (t1 ); pool.exe cute (t2); pool.exe cute (t3); pool.exe cute (t4); pool.exe cute (t5); // close the thread pool. shutdown ();}}
Output result
Pool-1-thread-1 is being executed... Pool-1-thread-1 is being executed... Pool-1-thread-1 is being executed... Pool-1-thread-1 is being executed... Pool-1-thread-1 is being executed...
2: newFixedThreadPool
TestFixedThreadPool. Java
Publicclass TestFixedThreadPool {publicstaticvoid main (String [] args) {// create a thread pool that can reuse a fixed number of threads ExecutorService pool = Executors. newFixedThreadPool (2); // creates and implements the Runnable interface object. Of course, the Thread object also implements the Runnable interface Thread t1 = new MyThread (); Thread t2 = new MyThread (); thread t3 = new MyThread (); Thread t4 = new MyThread (); Thread t5 = new MyThread (); // put the Thread into the pool and execute pool.exe cute (t1 ); pool.exe cute (t2); pool.exe cute (t3); pool.exe cute (t4); pool.exe cute (t5); // close the thread pool. shutdown ();}}
Output result
Pool-1-thread-1 is being executed... Pool-1-thread-2 is being executed... Pool-1-thread-1 is being executed... Pool-1-thread-2 is being executed... Pool-1-thread-1 is being executed...
3:NewCachedThreadPool
TestCachedThreadPool. java
Public class TestCachedThreadPool {public static void main (String [] args) {// create a thread pool that can reuse a fixed number of threads ExecutorService pool = Executors. newCachedThreadPool (); // creates and implements the Runnable interface object. Of course, the Thread object also implements the Runnable interface Thread t1 = new MyThread (); Thread t2 = new MyThread (); thread t3 = new MyThread (); Thread t4 = new MyThread (); Thread t5 = new MyThread (); // put the Thread into the pool and execute pool.exe cute (t1 ); pool.exe cute (t2); pool.exe cute (t3); pool.exe cute (t4); pool.exe cute (t5); // close the thread pool. shutdown ();}}
Output result:
Pool-1-thread-2 is being executed... Pool-1-thread-4 is being executed... Pool-1-thread-3 is being executed... Pool-1-thread-1 is being executed... Pool-1-thread-5 is being executed...
4:NewScheduledThreadPool
TestScheduledThreadPoolExecutor. java
Public class TestScheduledThreadPoolExecutor {public static void main (String [] args) {ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor (1); exec. scheduleAtFixedRate (new Runnable () {// an exception is triggered every time @ Override publicvoid run () {// throw new RuntimeException (); System. out. println ("====================") ;}, 1000,500 0, TimeUnit. MILLISECONDS); exec. scheduleAtFixedRate (new Runnable () {// print the System time at intervals to prove that the two are mutually independent @ Override publicvoid run () {System. out. println (System. nanoTime (); }}, 1000,200 0, TimeUnit. MILLISECONDS );}}
Output result
================838464454951683866438290348388643830710================839064385138383926438793198400643939383