1. Detailed explanation of the 7 parameters of the thread pool
Code example:
ThreadPoolExecutor threadPoolExecutor = new ThreadPoolExecutor(
1, // 核心线程数(也就是最小线程数)
2, // 最大线程数
5, // 线程闲置等待时间
TimeUnit.SECONDS, // 线程闲置等待时间单位
new ArrayBlockingQueue<>(200), // 消息队列容量
Executors.defaultThreadFactory(), // threadFactory 线程工厂
new ThreadPoolExecutor.CallerRunsPolicy()); // 拒绝策略
1. corePoolSize thread pool core thread size
A minimum number of threads will be maintained in the thread pool. Even if these threads are idle, they will not be destroyed unless allowCoreThreadTimeOut is set. The minimum number of threads here is corePoolSize. After the task is submitted to the thread pool, it will first check whether the current number of threads has reached the corePoolSize, if not, a new thread will be created to process the task.
2. maximumPoolSize The maximum number of threads in the thread pool
After the current number of threads reaches corePoolSize, if tasks continue to be submitted to the thread pool, the tasks will be cached in the work queue (described later). If the queue is also full, a new thread will be created to handle this. The thread pool will not create new threads indefinitely, it will have a limit on the maximum number of threads, which is specified by maximumPoolSize.
3. keepAliveTime idle thread survival time
If a thread is in an idle state and the current number of threads is greater than corePoolSize, the idle thread will be destroyed after a specified time. The specified time here is set by keepAliveTime
4, unit idle thread survival time unit
Unit of measure for keepAliveTime
5. workQueue work queue
After the new task is submitted, it will first enter the work queue, and then take the task out of the queue when the task is scheduled. Four work queues are provided in jdk:
(1)ArrayBlockingQueue
Array-based bounded blocking queue, sorted by FIFO. When new tasks come in, they will be placed at the end of the queue, and a bounded array can prevent resource exhaustion. When the number of threads in the thread pool reaches corePoolSize, and a new task comes in, the task will be placed at the end of the queue, waiting to be scheduled. If the queue is already full, a new thread is created, and if the number of threads has reached maxPoolSize, the rejection strategy will be executed.
(2)LinkedBlockingQuene
Unbounded blocking queue based on linked list (in fact, the maximum capacity is Interger.MAX), sorted according to FIFO. Due to the approximately unbounded nature of the queue, when the number of threads in the thread pool reaches corePoolSize, new tasks will always be stored in the queue, and basically will not create new threads until maxPoolSize (it is difficult to reach the number of Interger.MAX ), so when using this work queue, the parameter maxPoolSize actually has no effect.
(3)SynchronousQuene
A blocking queue that does not cache tasks, the producer puts a task and must wait until the consumer removes the task. That is to say, when a new task comes in, it will not be cached, but will be directly scheduled to execute the task. If there is no available thread, a new thread will be created. If the number of threads reaches maxPoolSize, the rejection strategy will be executed.
(4)PriorityBlockingQueue
Unbounded blocking queue with priority, the priority is realized by the parameter Comparator.
6. threadFactory thread factory
The factory used when creating a new thread can be used to set the thread name, whether it is a daemon thread, etc.
7. Handler rejection strategy
When the tasks in the work queue have reached the maximum limit, and the number of threads in the thread pool has also reached the maximum limit, if a new task is submitted, how to deal with it. The rejection strategy here is to solve this problem. jdk provides 4 rejection strategies:
(1)CallerRunsPolicy
Under this policy, the run method of the rejected task is directly executed in the caller thread, unless the thread pool has been shut down, the task is discarded directly.
(2)AbortPolicy
Under this policy, the task is discarded directly and a RejectedExecutionException is thrown.
(3)DiscardPolicy
Under this policy, the task is discarded directly and nothing is done.
(4)DiscardOldestPolicy
Under this strategy, discard the earliest task that entered the queue, and then try to put the rejected task into the queue
2. The difference between the two methods of submitting tasks execute() and submit()
1. The parameters received by the two are different
- The Execute() method can only receive parameters of type Runnable
- The submit() method can receive two types of parameters, Callable and Runnable
- Callable allows return values, while Runnable does not allow return values; Runnable does not allow exceptions to be thrown, and Callable allows exceptions to be thrown.
2. There will be a return value after submit() submits the task, but execute() does not
- The execute() method is mainly used to start the execution of the task, and there will be no return value after the task is executed.
- The submit() method is also used to start the execution of the task, but it will return the Future object after startup.
3. submit() is convenient for Exception handling
After the submit() method is executed, a Future object will be returned. We can call the .get() method of the Future object to judge whether the execution is successful (when the result is null, it means success, and the failure can be caught by catch to analyze the cause of the failure. )