JAVA thread pool and queue refused to learn strategies

Why use a thread pool?

In Java, if every time a request reaches a new thread is created, the cost is considerable. In actual use, creation time and system resources consumed by the new thread server spent on the creation and destruction of threads per request, and may even spend more time and resources than the actual user requests actually processed much more to be. In addition to the overhead of creating and destroying threads, thread activity also need to consume system resources. If you create too many threads in a JVM, it may cause the system due to excessive memory consumption, or "over-switching" and lead to insufficient system resources. In order to prevent the lack of resources, the application server needs some way to limit the number of requests processed any given time, reducing the number of creation and destruction of threads as possible, especially some large resource-consuming thread creation and destruction, try to use the existing objects to the service, which is why "pooled resources" techniques. 

The main thread pool thread to solve the life-cycle cost and the lack of resources, by reusing threads for multiple tasks, the overhead of thread creation are spread over a number of tasks, and because the thread already exists when a request arrives, it is eliminated Creating delay brings. In this way, you can immediately request a service, make the application more responsive. In addition, by adjusting the appropriate thread pool thread data can prevent the shortage of resources occurs.

ThreadPoolExecutor类

After JDK 1.5, Java provides a thread pool ThreadPoolExecutor class. The following from the constructor to analyze the use of the thread pool. 

public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler); 

Parameter name, description: 

* CorePoolSize thread pool to maintain the minimum number of threads 

* MaximumPoolSize thread pool to maintain the maximum number of threads 

* KeepAliveTime thread pool maintenance thread idle time allowed 

* WorkQueue task queue used to store task processing thread we have defined 

* ThreadFactory thread creation factory 

* Handler thread pool strategy rejected tasks 

ThreadPoolExecutor pool size is automatically adjusted according to the boundary and corePoolSize maximumPoolSize provided. When submitting a new task in method execute (Runnable), if the thread running less than corePoolSize, creating a new thread to handle the request. 

If the running thread equal corePoolSize, ThreadPoolExecutor added to the priority tasks in the queue until the queue is full, and do not create a new thread when idle threads. If corePoolSize and maximumPoolSize settings are the same, create a fixed-size thread pool. 

keepAliveTime: When the number of threads reaches maximumPoolSize, after a certain period of time, find the extra thread for the idle state, the recycling thread. keepAliveTime is the thread pool maximum free time. 

workQueue: When the core threads can not handle all the tasks New tasks are placed in the Queue.

There are three thread pool task queuing strategies:

Direct submission. Directly to the thread pool does not represent the policy tasks cache. New tasks submitted directly to the thread pool, when the thread pool is not idle threads, create a new thread to handle this task. This strategy requires the thread pool with the possibility of unlimited growth. Implemented as: SynchronousQueue

Bounded queue. When the thread pool reaches corePoolSize, New tasks are placed in a queue waiting to be processed in the queue. Bounded queue (such as ArrayBlockingQueue) helps prevent resource exhaustion, but may be difficult to adjust and control. Queue size and the maximum pool size may require a compromise between: the use of large queues and small pools minimizes CPU usage, operating system resources and context switching overhead, but doing so may result in decrease in throughput. If the task is frequently blocked (for example, if they are I / O boundary), the system may be more threads than your permission to arrange a time. Using a small queues generally requires larger pool size, high CPU utilization, but may encounter unacceptable scheduling overhead, it will also reduce the throughput.

Unbounded queue. Use unbounded queue (for example, does not have a predefined capacity LinkedBlockingQueue) will cause new tasks to wait in the queue when all corePoolSize threads are busy. Thus, thread creation will not exceed corePoolSize. (Thus, the value maximumPoolSize is also invalid.) When each task is completely independent of the other tasks that do not affect each task execution, suitable for use unbounded queue; for example, in a Web page server. This line may be used to handle transient burst request, when the command queue can handle more than the average arrive continuously, this strategy allows the possibility of unbounded growth has threads.

Refused strategy: when a steady stream of tasks over, and our system has to handle, however, when the policy we have to take is a denial of service. RejectedExecutionHandler interface provides an opportunity to reject the ways to customize job processing. In ThreadPoolExecutor already contains four processing strategies.

CallerRunsPolicy: running thread calls execute the task itself. This policy provides a simple feedback control mechanism, the speed can slow to submit new tasks. 

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {  if (!e.isShutdown()) { r.run(); }} 

This strategy obviously did not want to give up the mission. However, because the pool has no resources, and then directly call the execute thread to execute itself. (I always do not want to start discarding mission, but for some scenarios in terms likely to cause the current thread to be blocked. If all the threads are not executing, it may cause the program can not continue running. Depending needs The scenario may be right.)

AbortPolicy: handler refused to throw a run-time RejectedExecutionException 

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {throw new RejectedExecutionException();} 

This strategy is a direct throw, discard task. (Jdk default policy, refused to directly add a new task queue is full and full thread, and throw an exception, so that sometimes giving up is a kind of courage, in order to ensure the normal follow-up mission, discard some also can receive, remember to do recording)

DiscardPolicy: can not perform the task will be deleted 

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) {} 

This strategy and AbortPolicy almost the same, the task is discarded, but he does not throw an exception.

DiscardOldestPolicy: If the execution of the program has not been closed, is located at the head of the mission work queue will be deleted, and then retry the execution of the program (If it fails again, repeat this procedure) 

public void rejectedExecution(Runnable r, ThreadPoolExecutor e) { if (!e.isShutdown()) {e.getQueue().poll();e.execute(r); }} 

This policy will be slightly more complicated, first of all lost in the queue cache earliest task in the pool did not close the premise, and then try to run the task. This strategy requires proper care.

Executors factory

ThreadPoolExecutor achieve Executors class, which Executors class provides some static factory to produce some common thread pools, mainly in the following: 

1. newSingleThreadExecutor: create a thread pool of single-threaded. This is only a thread pool thread work, which is equivalent to a single-threaded serial execution of all tasks. If this thread only because of abnormal termination, then there will be a new thread to replace it. This thread pool to ensure that the order of execution of all tasks presented to the order of tasks. 

2. newFixedThreadPool: create a thread pool of fixed size. Each time you submit a task to create a thread, until the thread pool thread to reach the maximum size. Once the size of the thread pool reaches the maximum will remain unchanged, because if a thread execution abnormal end, the thread pool would add a new thread. (I use is this, the same as above, equivalent to creating the same corePoolSize, maximumPoolSize thread pool) 

3. newCachedThreadPool: Creating a cached thread pool. If the size of the thread pool threads exceeds the processing tasks required, it will recover partially free (60 seconds does not perform the task) threads, when the number of tasks, this thread pool and intelligently add a new thread to handle the task. This thread pool do not restrict the size of the thread pool, thread pool thread maximum size depends entirely on the size of the operating system (or JVM) that can be created.

For chestnuts

Test categories: ThreadPool, we created a newFixedThreadPool, a fixed maximum number of threads the thread pool size 3. Then throw into analog 10 mission. After the main thread will print one: the end of the main thread.

6113961-0752dd5a275f3a95
6113961-ff36a6161b65ec37

Thread pool creates three threads, tasks 0,1,2 respectively, due to the thread creation will take some time, so the first three threads of execution order with a certain randomness: the order is executed by the visible. At this time, followed by the main thread to thread pool task plugs, thread pool has reached the maximum number (3) threads, began to put into the queue. When a thread executing the task, straight out of the new task execution queue, the queue has the characteristics FIFO, the task execution is ordered behind. 

The Executors class look at the source code even understand. 

6113961-96bdca97e4bdffb8

Actually it creates a fixed number of threads have, ThreadPoolExecutor unbounded queue. Unbounded queue, the task will not refuse to submit, so use this method, you need to pay attention to the availability of resources being depleted. 

Test categories: TestThreadPool, using bounded queues (size 2), and a default deny policy ThreadPoolExecutor.

6113961-9f8f5eae28e2a4e7

Results of the:

6113961-62ec91291896967b

Thread pool creates two threads, respectively 0,1 mission, the thread pool reaches corePoolSize, New Tasks 2 and 3 are placed in the queue waiting to be processed, then the queue is full, but not over the thread pool thread to perform tasks 0, 1, the thread pool to create a new thread to perform a new task-4,5, reached maximumPoolSize. At this time, all tasks are executed is not over, but the main thread to continue to submit tasks, the thread pool to enter the default policy exception (AbortPolicy) denial of service.

Reproduced in: https: //www.jianshu.com/p/fe98c09ee84a

Guess you like

Origin blog.csdn.net/weixin_33724570/article/details/91184058