This article analyzes four Java thread pool usage for your reference. The specific content is as follows
1. The disadvantages of new Thread
Do you still just perform new Thread as follows when executing an asynchronous task?
new Thread(new Runnable() { @Override public void run() { // TODO Auto-generated method stub } }).start();Then you'll have too many outs, the disadvantages of new Thread are as follows:
a. The performance of new Thread is poor every time.
b. The threads lack unified management, which may create new threads without restrictions, compete with each other, and may occupy too much system resources to cause crashes or ooms.
c. Lack of more functions, such as timed execution, periodic execution, thread interruption.
Compared with new Thread, the advantages of the four thread pools provided by Java are:
a. Reuse existing threads to reduce the overhead of object creation and extinction, and perform well.
b. It can effectively control the maximum number of concurrent threads, improve the utilization rate of system resources, and avoid excessive resource competition and avoid blockage.
c. Provides functions such as timed execution, regular execution, single threading, concurrent number control, etc.
2. Java thread pool
Java provides four types of thread pools through Executors, namely:
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.
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.
newScheduledThreadPool Creates a fixed-length thread pool that supports timed and periodic task execution.
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).
(1) 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:
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, the first task has been completed, and the thread that executes the first task will be reused without creating a new thread every time.
(2) 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:
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 block e.printStackTrace(); }}});}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 Runtime.getRuntime().availableProcessors(). Please refer to PreloadDataCache.
(3) newScheduledThreadPool:
Create a fixed-length thread pool that supports timed and periodic task execution. The sample code for delayed execution is as follows:
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5); scheduledThreadPool.schedule(new Runnable() {@Overridepublic void run() { System.out.println("delay 3 seconds");}}, 3, TimeUnit.SECONDS);Indicates delay execution by 3 seconds.
The sample code is executed regularly as follows:
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {@Overridepublic void run() { System.out.println("delay 1 seconds, and excute every 3 seconds");}}, 1, 3, TimeUnit.SECONDS);It means that the delay is performed every 3 seconds after 1 second.
ScheduledExecutorService is safer and more powerful than Timer
(4) newSingleThreadExecutor:
Create 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). 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 block e.printStackTrace(); }} });}The results are output in sequence, which is equivalent to executing each task in sequence.
Most current GUI programs are single-threaded. Single threads in Android can be used for database operations, file operations, batch installation of applications, batch deletion of applications, etc., which are not suitable for concurrent but may block IO and affect the response of UI threads.
The function of thread pool:
The function of a thread pool is to limit the number of threads executed in the system.
Depending on the system environment, the number of threads can be automatically or manually set to achieve the best operation effect; less system resources are wasted, and more system congestion is not high. Use a thread pool to control the number of threads, and other threads are waiting in line. After a task is executed, the first task is taken from the queue to start execution. If there is no waiting process in the queue, this resource of the thread pool is waiting. When a new task needs to be run, if there are waiting worker threads in the thread pool, it can start running; otherwise, it will enter the waiting queue.
Why use thread pool:
1. Reduces the number of times threads are created and destroyed, and each worker thread can be reused and can perform multiple tasks.
2. The number of worker threads in the thread pool can be adjusted according to the system's ability to prevent the server from being sucked down due to excessive memory consumption (each thread requires about 1MB of memory. The more threads are opened, the greater the memory consumed, and finally the crash will be.
The top-level interface of thread pool in Java is Executor, but strictly speaking, Executor is not a thread pool, but just a tool for executing threads. The real thread pool interface is ExecutorService.
Several more important categories:
ExecutorService: A true thread pool interface.
ScheduledExecutorService: It can be similar to Timer/TimerTask, solving problems that require repeated tasks.
ThreadPoolExecutor: The default implementation of ExecutorService.
ScheduledThreadPoolExecutor: A class implementation of ScheduledExecutorService interface that inherits ThreadPoolExecutor, a periodic task scheduling class implementation.
It is quite complicated to configure a thread pool, especially when the principle of thread pool is not very clear. It is very likely that the configured thread pool is not better. Therefore, some static factories are provided in the Executors class to generate some commonly used thread pools.
1.newSingleThreadExecutor
Create a single thread pool. This thread pool has only one thread working, which is equivalent to a single thread performing all tasks in serial. If this unique thread ends because of the exception, then there will be a new thread to replace it. This thread pool ensures that the execution order of all tasks is executed in the order of the task submission.
2.newFixedThreadPool
Create a fixed-size thread pool. Each time a task is submitted, a thread is created until the thread reaches the maximum size of the thread pool. The thread pool size remains the same once it reaches its 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 to process the task,
Then some idle threads (no task execution in 60 seconds) will be recycled. When the number of tasks increases, this thread pool can intelligently add new threads to handle the task. This thread pool does not limit the thread pool size, which depends entirely on the maximum thread size that the operating system (or JVM) can create.
4.newScheduledThreadPool
Create a thread pool of unlimited size. This thread pool supports the need to perform tasks periodically and periodically.
Example code
1. Fixed-size thread pool, newFixedThreadPool:
package app.executors; import java.util.concurrent.Executors; import java.util.concurrent.ExecutorService; /** * Java thread: thread pool* * @author xiho */ public class Test { public static void main(String[] args) { // Create a thread pool with a fixed number of reusable threads ExecutorService pool = Executors.newFixedThreadPool(2); // Create thread 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 for execution pool.execute(t1); pool.execute(t2); pool.execute(t3); pool.execute(t4); pool.execute(t5); // Close the thread pool pool.shutdown(); } } class MyThread extends Thread { @Override public void run() { System.out.println(Thread.currentThread().getName() + "Executing..."); } }Output result:
pool-1-thread-1 is executing. . . pool-1-thread-3 is executing. . . pool-1-thread-4 is executing. . . pool-1-thread-2 is executing. . . pool-1-thread-5 is being executed. . .
Change the parameters in ExecutorService pool = Executors.newFixedThreadPool(5): ExecutorService pool = Executors.newFixedThreadPool(2), and the output result is:
pool-1-thread-1 is executing. . . pool-1-thread-1 is executing. . . pool-1-thread-2 is executing. . . pool-1-thread-1 is executing. . . pool-1-thread-2 is executing. . .
From the above results, we can see that the parameter of newFixedThreadPool specifies the maximum number of threads that can run. After adding more than this number of threads, they will not run. Secondly, the threads added to the thread pool are in the managed state, and the thread's operation is not affected by the joining order.
2. Single task thread pool, newSingleThreadExecutor:
Just change the ExecutorService pool = Executors.newFixedThreadPool(2) in the above code to ExecutorService pool = Executors.newSingleThreadExecutor();
Output result:
pool-1-thread-1 is executing. . . pool-1-thread-1 is executing. . . pool-1-thread-1 is executing. . . pool-1-thread-1 is executing. . . pool-1-thread-1 is executing. . .
It can be seen that every time you call the execute method, the thread-1 run method is actually called in the end.
3. Variable size thread pool, newCachedThreadPool:
Similar to the above, just change the way the pool is created: ExecutorService pool = Executors.newCachedThreadPool();
Output result:
pool-1-thread-1 is executing. . . pool-1-thread-2 is executing. . . pool-1-thread-4 is executing. . . pool-1-thread-3 is executing. . . pool-1-thread-5 is being executed. . .
This method is characterized by the fact that new thread pools can be created as needed, but they will be reused when previously constructed threads are available.
4. Delay connection pool, newScheduledThreadPool:
public class TestScheduledThreadPoolExecutor { public static void main(String[] args) { ScheduledThreadPoolExecutor exec = new ScheduledThreadPoolExecutor(1); exec.scheduleAtFixedRate(new Runnable() {//Exception is triggered every once in a while @Override publicvoid run() { //throw new RuntimeException(); System.out.println("=========================================================================================================================================================================================================================================================================================================================================================================================== TimeUnit.MILLISECONDS); exec.scheduleAtFixedRate(new Runnable() {//Print the system time every once in a while, proving that the two have no influence on each other @Override publicvoid run() { System.out.println(System.nanoTime()); } }, 1000, 2000, TimeUnit.MILLISECONDS); }}Output result:
================838464454951683866438290348388643830710================839064385138383926438793198400643939383
The above is all about this article, I hope it will be helpful to everyone's learning.