Detailed introduction of four common thread pools in Java
- 2021-07-03 00:07:29
- OfStack
1. Introduction to Thread Pool
1. Thread pool concept:
Thread pool is to create 1 threads first, and their collection is called thread pool. Using thread pool can improve performance very well. When the system starts, the thread pool creates a large number of idle threads. When the program passes a task to the thread pool, the thread pool will start a thread to execute this task. After the execution, the thread will not die, but return to the thread pool again to become idle, waiting for the next task to be executed.
2. How Thread Pool Works
2.1 In the programming mode of thread pool, the task is submitted to the whole thread pool, instead of directly submitting to a certain thread. After the thread pool gets the task, it will look internally for whether there are idle threads, and if there are, it will hand over the task to a certain idle thread.
2.2 One thread can only perform one task at a time, but multiple tasks can be submitted to one thread pool at the same time.
3. Reasons for using thread pools:
Multi-threaded running time, the system constantly starts and closes new threads, the cost is very high, which will consume system resources excessively, and the danger of switching threads excessively, which may lead to the collapse of system resources. At this time, the thread pool is the best choice.
2. Detailed explanation of 4 common thread pools
1. Introduction to the return value of thread pool ExecutorService:
ExecutorService
Is a class provided by Java for managing thread pools. Two functions of this class: control the number of threads and reuse threads
2. The specific four commonly used thread pool implementations are as follows: (The return values are all ExecutorService)
2.1
Executors.newCacheThreadPool()
: Can cache thread pool, first check whether there are previously established threads in the pool, and if so, use it directly. If not, a new thread is created and added to the pool. The cache pool is usually used to perform asynchronous tasks with short lifetime
Sample code:
package com.study.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExecutorTest {
public static void main(String[] args) {
// Create 1 Cacheable thread pool
ExecutorService cachedThreadPool = Executors.newCachedThreadPool();
for (int i = 0; i < 10; i++) {
try {
//sleep It is obvious that the previous threads in the thread pool are used, and no new threads are created
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
cachedThreadPool.execute(new Runnable() {
public void run() {
// Print the information of the executing cache thread
System.out.println(Thread.currentThread().getName()+" Being executed ");
}
});
}
}
}
Output:
pool-1-thread-1 being executed
pool-1-thread-1 being executed
pool-1-thread-1 being executed
pool-1-thread-1 being executed
pool-1-thread-1 being executed
pool-1-thread-1 being executed
pool-1-thread-1 being executed
pool-1-thread-1 being executed
pool-1-thread-1 being executed
pool-1-thread-1 is being executed
The thread pool is infinite. When the last 1 task has been completed when the current task is executed, the thread executing the last 1 task will be reused instead of creating a new thread every time
2.2
Executors.newFixedThreadPool(int n)
Create a pool of reusable threads with a fixed number, and run these threads in a shared unbounded queue.
Sample code:
package com.study.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class ThreadPoolExecutorTest {
public static void main(String[] args) {
// Create 1 A fixed number of thread pools can be reused
ExecutorService fixedThreadPool = Executors.newFixedThreadPool(3);
for (int i = 0; i < 10; i++) {
fixedThreadPool.execute(new Runnable() {
public void run() {
try {
// Print the information of the executing cache thread
System.out.println(Thread.currentThread().getName()+" Being executed ");
Thread.sleep(2000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
}
Output:
pool-1-thread-1 being executed
pool-1-thread-2 being executed
pool-1-thread-3 being executed
pool-1-thread-1 is being executed
pool-1-thread-2 being executed
pool-1-thread-3 being executed
pool-1-thread-1 being executed
pool-1-thread-2 being executed
pool-1-thread-3 being executed
pool-1-thread-1 being executed
Because the thread pool size is 3, sleep is 2 seconds after each task outputs the print result, so three results are printed every two seconds.
The size of the fixed-length thread pool is best set according to system resources. Such as
Runtime.getRuntime().availableProcessors()
2.3
Executors.newScheduledThreadPool(int n)
Create a fixed-length thread pool to support timed and periodic task execution
Delayed execution of the sample code:
package com.study.test;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ThreadPoolExecutorTest {
public static void main(String[] args) {
// Create 1 Fixed-length thread pool, supporting timed and periodic task execution-delayed execution
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
// Delay 1 Second execution
scheduledThreadPool.schedule(new Runnable() {
public void run() {
System.out.println(" Delay 1 Second execution ");
}
}, 1, TimeUnit.SECONDS);
}
}
Output:
Delay execution by 1 second
Execute the sample code periodically:
package com.study.test;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
public class ThreadPoolExecutorTest {
public static void main(String[] args) {
// Create 1 Fixed-length thread pool, supporting timed and periodic task execution-regular execution
ScheduledExecutorService scheduledThreadPool = Executors.newScheduledThreadPool(5);
// Delay 1 Every second after 3 Second execution 1 Times
scheduledThreadPool.scheduleAtFixedRate(new Runnable() {
public void run() {
System.out.println(" Delay 1 Every second after 3 Second execution 1 Times ");
}
}, 1, 3, TimeUnit.SECONDS);
}
}
Output:
Execute once every 3 seconds after 1 second delay
Execute once every 3 seconds after 1 second delay
.............
2.4
Executors.newSingleThreadExecutor()
Creates a single-threaded thread pool that executes tasks with only one worker thread, ensuring that all tasks are executed in the specified order (FIFO, LIFO, priority).
Sample code:
package com.study.test;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
public class TestThreadPoolExecutor {
public static void main(String[] args) {
// Create 1 Single-threaded thread pool
ExecutorService singleThreadExecutor = Executors.newSingleThreadExecutor();
for (int i = 0; i < 10; i++) {
final int index = i;
singleThreadExecutor.execute(new Runnable() {
public void run() {
try {
// The results are output in turn, which is equivalent to executing each task in sequence
System.out.println(Thread.currentThread().getName()+" Being executed , The printed value is :"+index);
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
});
}
}
}
Output:
pool-1-thread-1 is being executed and the printed value is: 0
pool-1-thread-1 is being executed and the printed value is: 1
pool-1-thread-1 is being executed, and the printed value is: 2
pool-1-thread-1 is being executed, and the printed value is: 3
pool-1-thread-1 is being executed, and the printed value is: 4
pool-1-thread-1 is being executed, and the printed value is: 5
pool-1-thread-1 is being executed, and the printed value is: 6
pool-1-thread-1 is being executed, and the printed value is: 7
pool-1-thread-1 is being executed, and the printed value is: 8
pool-1-thread-1 is being executed, and the printed value is: 9
3. Buffer queue BlockingQueue and custom thread pool ThreadPoolExecutor
1. Introduction to Buffer Queue BlockingQueue:
BlockingQueue is a double buffered queue. BlockingQueue uses two queues internally, allowing two threads to store and take out one operation to the queue at the same time. While ensuring concurrency security, it improves the access efficiency of queues.
2. Several commonly used BlockingQueue:
ArrayBlockingQueue (int i): A specified size BlockingQueue whose construction must specify a size. The objects it contains are sorted in FIFO order. LinkedBlockingQueue () or (int i): The size of BlockingQueue is not fixed. If the size is specified when it is constructed, the generated BlockingQueue has a size limit, and the size is determined by Integer. MAX_VALUE. The objects it contains are sorted in FIFO order. PriorityBlockingQueue () or (int i): Similar to LinkedBlockingQueue, but the ordering of the objects it contains is not FIFO, but is determined by the natural order of the objects or the Comparator of the constructor. SynchronizedQueue (): Special BlockingQueue, which must be operated alternately by placing and fetching.3. Custom thread pool (ThreadPoolExecutor with BlockingQueue):
Custom thread pools, which can be created using the ThreadPoolExecutor class, have multiple constructors to create thread pools.
Common constructors:
ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue)
Sample code:
package com.study.test;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
class TempThread implements Runnable {
@Override
public void run() {
// Print the information of the executing cache thread
System.out.println(Thread.currentThread().getName() + " Being executed ");
try {
// sleep1 Second guarantee 3 Tasks are in the 3 Execute on three threads
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public class TestThreadPoolExecutor {
public static void main(String[] args) {
// Create an array buffer wait queue
BlockingQueue<Runnable> bq = new ArrayBlockingQueue<Runnable>(10);
// ThreadPoolExecutor: Create a custom thread pool with the number of threads saved in the pool 3 The maximum number of threads allowed is 6
ThreadPoolExecutor tpe = new ThreadPoolExecutor(3, 6, 50, TimeUnit.MILLISECONDS, bq);
// Create 3 Tasks
Runnable t1 = new TempThread();
Runnable t2 = new TempThread();
Runnable t3 = new TempThread();
// Runnable t4 = new TempThread();
// Runnable t5 = new TempThread();
// Runnable t6 = new TempThread();
// 3 Tasks are in the 3 Execute on three threads
tpe.execute(t1);
tpe.execute(t2);
tpe.execute(t3);
// tpe.execute(t4);
// tpe.execute(t5);
// tpe.execute(t6);
// Close custom thread pool
tpe.shutdown();
}
}
Output:
pool-1-thread-1 being executed
pool-1-thread-2 being executed
pool-1-thread-3 being executed
Summarize