In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-16 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/03 Report--
This article mainly explains "what is the working principle of thread pool". The content of the explanation is simple and clear, and it is easy to learn and understand. let's follow the editor's train of thought to study and learn "what is the working principle of thread pool"?
Self-introduction of thread pool
I am a thread pool (ThreadPoolExecutor). My main job is to manage multiple threads (Thread) here, so that they can execute multiple tasks concurrently without causing great system overhead. Some people don't understand what the overhead is to create a thread. I just need to new a Thread to let it run. Here I want to explain briefly:
In fact, the thread model in Java is based on the operating system native thread model, that is to say, threads in Java are actually implemented based on kernel threads. Thread creation, destructing and synchronization all require system calls, while system calls need to switch back and forth between the user mode and the kernel, which is relatively expensive. The life cycle of a thread includes "thread creation time", "thread execution time", "thread destruction time", creation and destruction all need to cause system calls.
Each Thread needs to be supported by a kernel thread, which means that each Thread needs to consume certain kernel resources (such as the stack space of the kernel thread), because the Thread that can be created is limited, and the default thread stack size of a thread is 1m. If you create a thread for each task, 1024 tasks just to create a thread takes up 1 G of memory, and the system crashes easily.
CorePoolSize
So my main role is to reduce thread creation time and destruction time, thread creation does not immediately destroy it, but resident with me, on call, I call these resident threads as core threads, the number of core threads should not be too much, so I specified the number of them (corePoolSize), assuming 3.
"Thread pool, this is one of my tasks, please help me execute it." the main thread threw me the task and returned immediately, so I quickly called the execute method to deal with the task thrown to me (Runnable).
Public interface Executor {void execute (Runnable command);}
Since I haven't performed a task since I was born, the core thread has always been 0, so in this method I created a thread as the core thread.
"Thread pool, here comes the task again, please help me to execute it." here comes the task again! So I called execute again and created another core thread with a core thread of 2.
After a period of time, the first core thread has finished executing the task and is idle, and then the task comes again.
"Thread pool, this is one of my tasks, please execute it for me." the main thread stacks the next sentence and then leaves. At this time, a core thread is busy and a core thread is idle. Many people may mistakenly think that since there is a core thread idle here, you can leave the task to this thread. There is no need to create a core thread, but in fact, as long as the current number of core threads is less than the original corePoolSize. Regardless of whether the current core thread is idle or not, I will still create another core thread, mainly to ensure that the number of core threads reaches the number we set as soon as possible, so that if a lot of tasks pour in later, these core threads that have been created will be ready to deal with these tasks immediately without the time-consuming operation of creating threads.
After the above operation, the number of core threads has reached the initial number of 3.
WorkQueue
"Thread pool, the task is coming again, please help me execute it." the familiar voice comes again. At this time, the number of core threads has reached the number we set. Of course, you can create another thread, but it will cause a system call. The overhead is relatively high. In fact, the core thread may be idle immediately after a very short period of time. It is better to put the task into a queue and let these core threads pick it up.
Smart you must have found that this is the typical producer-consumer model. Threads in the thread pool only need to cycle to the workQueue queue to get tasks. In order to avoid the problem that CPU resources are occupied because workQueue is an empty thread, workQueue here uses a blocking queue. The so-called blocking means that if the workQueue is empty, the thread that gets the element will wait for the queue to become non-empty, once there are new tasks in the queue. Wakes up the waiting thread.
Voiceover: thread waiting refers to calling LockSupport.park to change a thread from a running state to a blocking state, so that the thread does not occupy CPU resources
But the good times did not last long, the boss of JVM gave me feedback on the problem of OOM. As soon as I looked at the problem, I understood that it was the novice programmer who declared that he used an unbounded queue when creating me, resulting in the core thread being unable to process tasks in time, while tasks were continuously added to the workQueue (that is, the speed of production tasks is much faster than that of consumer tasks), resulting in workQueue getting bigger and bigger, resulting in OOM!
The solution is simple: use bounded queues, so that when the workQueue is full, you cannot add tasks, which will not cause the workQueue to grow infinitely and cause OOM.
Voiceover: the so-called bounded queue refers to a queue with a fixed size, and when the elements in the queue exceed this size, you can no longer plug tasks into this queue, while the unbounded queue can join the queue directly until it overflows, which is easy to cause OOM, so you should try to use bounded queues when creating thread pools.
MaximumPoolSize
After switching workQueue to a bounded queue, OOM never appeared again, but because the main thread kept losing some time-consuming tasks, the core thread still couldn't handle it, and the workQueue was soon full again. Then I thought of another parameter, maximumPoolSize, which defines the maximum number of threads I can create. When other threads want to plug tasks into the queue, but find that workQueue is full. Since the thread currently with me has not yet reached the maximumPoolSize (assuming it was originally specified as 5), I created another thread to handle the task.
Voiceover: when the workQueue is full, if the number of threads in the current thread pool > = corePoolSize and
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.