In the previous study, I learned the concept of database connection pool. The purpose of database connection pool design is to prevent frequent creation of database connection objects, and to manage database connection objects uniformly, which can reduce the cost of the system.
overview
Pool concept:
Similar to a collection of containers, objects are stored in this collection of containers, which can be managed uniformly
Thread Pool:
Similar to the database connection pool, in order to reduce the overhead of creating threads, a thread pool is specially set up to manage the created thread tasks
Each piece of thread code will not be destroyed immediately after running, but will return to the thread pool and wait for the next object to be used
After jdk5, the built-in thread pool ThreadPoolExecutor is added, and Executor is provided to create different types of thread pools
However, the use of Executor to create other thread pools is prohibited in the Java Development Code Songshan Edition, and it is not recommended to use these thread pools directly
Advantages of thread pool
Reduces the overhead of creating and destroying threads
Threads are conveniently managed in a thread pool
The thread has been created in the thread pool, and the response speed is fast when used
Thread pool parameter settings
There are seven parameters in the constructor of the thread pool creation
1.corePoolSize: The size of the core thread pool
2. maximumPoolSize: The maximum number of threads that can be created in the thread pool
3. keepAliveTime: When the number of threads is greater than corePoolSize, the survival time of the task termination thread will be calculated. If the survival time is too long and there is no task execution, the thread will be cleared until the number of threads is less than or equal to corePoolSize
4.unit: Set the time unit of keepAliveTime, and use the static properties in the TimeUnit class to assign values
5.workQueue: a blocking queue, unexecuted tasks in the thread pool will be stored in the queue waiting to be used
ArrayBlockingQueue: It is a bounded blocking queue implemented by an array, the length must be set when creating, and tasks are sorted by FIFO
LinkedBlockingQueue: A blocking queue based on a linked list structure. Tasks are sorted by FIFO. The capacity can be set optionally. If not set, the default is a maximum length of Integer.MAX_VALUE
6. threadFactory: thread factory, mainly used to create threads;
7.handler: Indicates the strategy when the thread pool is full and refuses to process new tasks. There are four strategies in total
AbortPolicy(): Throwing an exception does not execute the task
DiscardPolicy(): Directly reject the task and do not execute it
DiscardOldestPolicy(): Find a task with the longest waiting time in the thread pool and discard it, increasing the task
CallerRunsPolicy(): As long as the thread pool is not closed, the task will be handed over to the main thread for execution
Workflow of the thread pool
1. When a task is created, it will go to the core thread pool to obtain thread execution. If there is no thread in the core thread pool, create a thread for execution
2. If the core thread pool is full, it will enter the task blocking queue
3. If the blocking queue is full, the number of threads will be judged. If the maximumPoolSize is not reached, a thread will be created to perform tasks in the non-core thread pool
4. If the non-core thread pool is full, and the blocking queue is also full, and a new task is added at this time, the rejection strategy will be executed directly
The difference between execute and submit
Both are thread task submission methods, the former has no return value, and the latter has a return value
Close the thread pool
Closing the thread pool can be achieved by calling the shutdownNow and shutdown methods
shutdownNow : Issue interrupt() to all the tasks that are being executed, stop the execution, cancel all the tasks that have not started to execute, and return the list of tasks that have not started yet.
shutdown : When we call shutdown, the thread pool will no longer accept new tasks, but it will not forcibly terminate tasks that have been submitted or are being executed.
Example of thread pool usage:
public class Test {
public static void main(String[] args) {
//创建线程池
ThreadPoolExecutor executor = new ThreadPoolExecutor(2,//核心线程池数
5, //最大线程数
200,//线程数量多时的空闲线程存活时间
TimeUnit.MILLISECONDS,//keepAiveTime的单位
new ArrayBlockingQueue<>(2),//阻塞队列为数组队列且长度为2
Executors.defaultThreadFactory(),//线程工厂
new ThreadPoolExecutor.CallerRunsPolicy());//拒绝策略
executor.prestartAllCoreThreads();
for(int i=1;i<=8;i++){//一共八个个任务
MyTask myTask = new MyTask(i);
executor.execute(myTask);//添加任务到线程池
//Future<?> submit = executor.submit(myTask);
//submit.get();//返回值
}
executor.shutdown();
}
}
MyTask class
public class MyTask implements Runnable {
private int taskNum;
public MyTask(int num) {
this.taskNum = num;
}
@Override
public void run() {
try {
Thread.currentThread().sleep(4000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName()+":task "+taskNum+"执行完毕");
}
}