In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-02-23 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/01 Report--
This article will explain in detail what are the knowledge points about Java thread pool, the editor thinks it is very practical, so I share it for you as a reference. I hope you can get something after reading this article.
1. Number of threads using the development protocol
There are three mandatory specifications for the use of threads and thread pools in Alibaba's development manual.
[force] specify a meaningful thread name when creating a thread or thread pool to facilitate backtracking in case of error.
Positive example: customize the thread factory and group it according to external characteristics, for example, the call from the same computer room assigns the computer room number to whatFeatureOfGroup
Public class UserThreadFactory implements ThreadFactory {private final String namePrefix;private final AtomicInteger nextId = new AtomicInteger (1); / * defines the thread group name, which is very helpful when using jstack to troubleshoot problems * / UserThreadFactory (String whatFeatureOfGroup) {namePrefix = "From UserThreadFactory's" + whatFeatureOfGroup + "- Worker-";} @ Overridepublic Thread newThread (Runnable task) {String name = namePrefix + nextId.getAndIncrement (); Thread thread = newThread (null, task, name, 0); System.out.println (thread.getName ()); return thread;}}
[mandatory] Thread resources must be provided through the thread pool, and it is not allowed to explicitly create threads in the application.
Note: the advantage of thread pool is to reduce the time spent on creating and destroying threads and the overhead of system resources, and to solve the problem of insufficient resources.
If you do not use thread pools, it is possible for the system to create a large number of similar threads, resulting in running out of memory or "excessive switching".
[mandatory] Thread pools are not allowed to be created using Executors, but through ThreadPoolExecutor, which
The same way of processing makes the writing students more clear about the running rules of the thread pool and avoid the risk of resource exhaustion.
Note: the disadvantages of the thread pool object returned by Executors are as follows:
1) FixedThreadPool and SingleThreadPool:
The allowed request queue length is Integer.MAX_VALUE, which may pile up a large number of requests, resulting in OOM.
2) CachedThreadPool:
The number of creation threads allowed is Integer.MAX_VALUE, which may create a large number of threads, resulting in OOM.
2. ThreadPoolExecutor source code 1. Constructor function
UML figure:
There are four constructors for ThreadPoolExecutor, but they all end up calling the same one:
two。 Core parameters
CorePoolSize = > number of core threads in the thread pool
MaximumPoolSize = > maximum number of thread pools
KeepAliveTime = > the amount of time to keep alive after the worker thread of the thread pool is idle. If there are many tasks and the execution time of the task is relatively short, you can increase the keepAliveTime to improve thread utilization.
Unit = > time unit
WorkQueue = > the buffer queue used by the thread pool. The queue types are:
ArrayBlockingQueue, a bounded blocking queue based on array structure, sorts tasks according to the principle of FIFO (first in first out). With this queue, the maximum number of threads that can be created in the thread pool is maximumPoolSize
LinkedBlockingQueue, an unbounded blocking queue based on linked list structure, sorts tasks according to FIFO (first-in, first-out) principle, and its throughput is higher than that of ArrayBlockingQueue. With this queue, the maximum number of threads that can be created in the thread pool is corePoolSize. The static factory method Executor.newFixedThreadPool () uses this queue.
SynchronousQueue, a blocking queue that does not store elements. The operation of adding a task must wait until the remove operation of another thread, otherwise the add operation will always be blocked. The static factory method Executor.newCachedThreadPool () uses this queue.
PriorityBlokingQueue: an unbounded blocking queue that supports priority. With this queue, the maximum number of threads that can be created in the thread pool is corePoolSize.
ThreadFactory = > Thread Pool creates factories used by threads
Handler = > Thread pool's strategies for rejecting tasks. There are four main types of rejection policies:
AbortPolicy: when you cannot handle a new task, throw an exception directly, which is the default policy.
CallerRunsPolicy: use the caller's thread to execute the task.
DiscardOldestPolicy: discards the first task in the blocking queue and executes the current task.
DiscardPolicy: discard the task directly.
3.execute () method
If there are fewer threads currently running than corePoolSize, a new worker thread is created to execute the task (this step requires a global lock).
If the currently running thread is greater than or equal to corePoolSize and the BlockingQueue is not full, the task is added to the BlockingQueue.
If the BlockingQueue is full and the currently running thread is smaller than maximumPoolSize, a new worker thread is created to execute the task (this step requires a global lock).
If the currently running thread is greater than or equal to maximumPoolSize, the task is rejected and the RejectExecutionHandler.rejectExecution () method is called. That is, the saturation strategy is called to process the task.
3. The workflow of thread pool
Execution logic description:
Determine whether the number of core threads is full, and the number of core threads is related to the corePoolSize parameter. If not, create a thread to execute the task.
If the core thread pool is full, determine whether the queue is full. Whether the queue is full is related to the workQueue parameter. If not, join the queue.
If the queue is full, determine whether the thread pool is full, and whether the thread pool is full is related to the maximumPoolSize parameter. If not, the created thread executes the task.
If the thread pool is full, the reject policy is used to deal with the tasks that cannot be executed. The reject policy is related to the handler parameter.
4. Executors creation returns ThreadPoolExecutor object (not recommended)
There are three ways for Executors to create a return ThreadPoolExecutor object:
1. Executors#newCachedThreadPool = > create a cacheable thread pool
CorePoolSize = > 0, the number of core thread pools is 0
MaximumPoolSize = > Integer.MAX_VALUE, the maximum number of threads can be considered unlimited
KeepAliveTime = > 60L
Unit = > seconds
WorkQueue = > SynchronousQueue
Disadvantages: maximumPoolSize = > Integer.MAX_VALUE may cause OOM
2. Executors#newSingleThreadExecutor = > create a single thread pool
SingleThreadExecutor is a single-thread thread pool with only one core thread:
CorePoolSize = > 1, the number of core thread pools is 1
MaximumPoolSize = > 1, only one non-core thread can be created
KeepAliveTime = > 0L
Unit = > Ms
WorkQueue = > LinkedBlockingQueue
Disadvantages: LinkedBlockingQueue is a queue of length Integer.MAX_VALUE, which can be thought of as an unbounded queue, so an unlimited number of tasks can be inserted into the queue, which can easily cause OOM exceptions when resources are limited.
3. Executors#newFixedThreadPool = > create a fixed-length thread pool
CorePoolSize = > 1, the number of core thread pools is 1
MaximumPoolSize = > 1, only one non-core thread can be created
KeepAliveTime = > 0L
Unit = > Ms
WorkQueue = > LinkedBlockingQueue
It is similar to SingleThreadExecutor, except that the number of core threads is different, and because it uses LinkedBlockingQueue, it is easy to cause OOM exceptions when resources are limited.
5. Reasonable configuration of thread pool
Analyze the characteristics of a task from the following perspectives:
The nature of tasks: CPU-intensive tasks, IO-intensive tasks and mixed tasks.
Priority of the task: high, medium, low.
The execution time of the task: long, medium and short.
Task dependency: whether to rely on other system resources, such as database connections.
Tasks with different nature can be handled separately with thread pools of different sizes. You can get the number of CPU of the current device through the Runtime.getRuntime (). AvailableProcessors () method.
CPU-intensive tasks: configure threads as small as possible, such as configuring thread pools with cpu cores + 1 threads.
IO-intensive tasks: since threads are not always executing tasks, configure as many threads as possible, such as 2 ∗ Ncpu.
Mixed task: if it can be split, split it into a CPU-intensive task and an IO-intensive task. As long as the execution time of the two tasks is not too different, the throughput of decomposed execution is higher than that of serial execution; if the difference between the execution time of the two tasks is too large, it is not necessary to decompose.
Tasks with different priorities can be handled using the priority queue PriorityBlockingQueue, which allows high-priority tasks to be executed first. However, if high-priority tasks are added to the blocking queue all the time, low-priority tasks may never be executed.
Tasks with different execution times can be handed over to thread pools of different sizes, or priority queues can be used to allow tasks with short execution times to be executed first.
Tasks that rely on database connection pooling, because threads need to wait for the database to return results after submitting the SQL, and the number of threads should be set to a large number in order to make better use of CPU.
It is recommended to use bounded queues, which can increase the stability and early warning ability of the system. You can make it a little bigger as needed, such as thousands. With unbounded queues, the queue of the thread pool becomes larger and larger, which may fill up memory, making the entire system unavailable.
There are several comparative recommendations for handling rejection strategies:
Catch the RejectedExecutionException exception in the program, and handle the task in the catch exception. The CallerRunsPolicy reject policy is used for the default reject policy, which leaves the task to the thread calling execute to execute [usually the main thread]. At this time, the main thread will not be able to submit any tasks for a period of time, thus allowing the worker thread to process the executing task. At this time, the submitted thread will be saved in the TCP queue, and the fullness of the TCP queue will affect the client. This is a gentle performance degradation custom reject policy, which only needs to implement the RejectedExecutionHandler API. If the task is not particularly important, it is also possible to use DiscardPolicy and DiscardOldestPolicy reject policies to discard the task. If you use the static method of Executors to create a ThreadPoolExecutor object, you can use Semaphore to limit the flow of task execution and avoid OOM exceptions.
6. Refusal strategy
There are several comparative recommendations:
Catch the RejectedExecutionException exception in the program, and handle the task in the catch exception. For the default deny policy
Using the CallerRunsPolicy reject policy, the task is handed over to the thread calling execute to execute [usually the main thread], where the main thread will not be able to submit any tasks for a period of time, causing the worker thread to process the executing task. At this point, the submitted thread will be saved in the TCP queue, and the full TCP queue will affect the client, which is a gentle performance degradation.
To customize the rejection policy, you only need to implement the RejectedExecutionHandler interface.
If the task is not particularly important, it is also possible to use DiscardPolicy and DiscardOldestPolicy reject policies to discard the task. If you use the static method of Executors to create a ThreadPoolExecutor object, you can use Semaphore to limit the flow of task execution and avoid OOM exceptions.
7. Five running states of thread pool
Thread status:
Unlike thread states, thread pools also have the following states:
RUNNING: the thread pool in this state can both accept newly submitted tasks and handle tasks in blocking queues.
SHUTDOWN: the thread pool in this state cannot receive newly submitted tasks, but can handle tasks in blocking queues. (the government service hall no longer allows people to get their numbers, and after dealing with the affairs at hand and queuing up, they will get off work.)
When in the RUNNING state, calling the shutdown () method brings the thread pool into that state.
Note: the finalize () method also implicitly calls the shutdown () method during execution.
STOP: the thread pool in this state does not accept newly committed tasks, does not process tasks in blocking queues, and interrupts tasks that are in progress. The government service hall is no longer in service, and the number taking, queuing, and work at hand have all stopped. )
When the thread pool is in the RUNNING or SHUTDOWN state, calling the shutdownNow () method causes the thread pool to enter that state
TIDYING: if all tasks are terminated, workerCount (number of valid threads) = 0.
After the thread pool enters this state, the terminated () hook method is called to enter the TERMINATED state.
TERMINATED: enters this state after the terminated () hook method is executed, and nothing is done in the default terminated () hook method.
This is the end of this article on "what are the knowledge points of Java thread pool". I hope the above content can be of some help to you, so that you can learn more knowledge. if you think the article is good, please share it for more people to see.
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.