In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-01-18 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly explains the "java virtual machine multithreading knowledge points", the content of the explanation is simple and clear, easy to learn and understand, the following please follow the editor's ideas slowly in depth, together to study and learn "what are the java virtual machine multithreading knowledge points" bar!
1. Basic parameters of thread pool
Take the creation of Executors.newFixedThreadPool () as an example:
Imagine, if you create a thread pool, what parameters do you think the pool has? First of all, the pool must have a maximum value; then it is hoped that the number of threads in this pool will have a warning line, and when it comes to this warning line, the thread pool is temporarily full. If anyone still comes to pick up the threads at this time, we have to pick up these people and throw them in a place to line them up and tell them: please wait a moment and wait for our threads to deal with your business when they are free. Then, if the queuing place is full, Mudd, a lot of people, so the thread pool will find a way to cobble together and come up with a few more threads to deal with; finally, if these threads are still not enough, and the queuing place is always full, so the thread pool is angry, so so many people can, if anyone comes quickly let it go.
Here are a few things we need to know:
1 the warning line here is called core thread pool size (corePoolSize)
two。 The maximum is still called the maximum number of threads in the thread pool (maximumPoolSize)
3. The queuing place is called BlockingQueue, which is used to hold the tasks that our thread is going to do. There are several types of queues, which we will analyze later.
4. Another parameter is keepAliveTime: thread survival time, which means that when the total number of threads in the pool is greater than the number of core thread pools, close the idle threads in the pool and ensure that the total number of threads is maintained at or below the number of core thread pools.
Now let's sort out the logic:
Current number of threads in the pool number of core thread pool: put redundant tasks in the queue
The queue is full, there are tasks coming, and the thread pool continues to create threads until the maximum number of thread pools is reached.
There are also tasks coming. There will be a saturation strategy. By default, tasks that continue to be discarded will be discarded directly.
two。 Thread pool type
The thread pool we used in the previous section is as follows:
ExecutorService pool = Executors.newFixedThreadPool (3); pool.execute (new RunnableImpl ("play games"))
We created a thread pool through the static method of the Executors class, so let's go into this class and see if this class has a way to create other kinds of thread pools.
Let's talk briefly about what these four kinds are used for.
NewFixedThreadPool (int): this thread pool is the way mentioned above, and it is also the thread pool where we focus on the source code.
NewSingThreadExecutor (): this is not a thread pool, because there is only one thread in it, and it comes with a queue, so whenever a task comes, it will save the task to the queue, and then the thread will slowly execute it one by one.
NewCachedThreadPool (): thread pool for unlimited threads
NewScheduledThreadPool (int): a timed thread pool that allows threads in the thread pool to delay the execution of tasks for a specified time
3.Executors inheritance structure
We can see that what is actually instantiated is a ThreadPoolExecutor object that is used by a thread to handle the incoming task:
Let's take a look at this inheritance structure.
Executor interface: only execute () is defined; this method, waiting for the subclass to implement
ExecutorService interface: inherits the Execute interface, and declares the shutdown () method and submit () method, waiting for the subclass to implement
AbstractExecutorService abstract class: initially implements the submit () method, but internally calls the execute () method to perform the task
ThreadPoolExecutor class: this class implements a lot of methods, including shutdown () and execute () methods.
4. Look at the source code of the execute () method
Next, we mainly look at the internal implementation of the execute () method, and we will almost know the implementation principle of this method.
Public void execute (Runnable command) {if (command = = null) throw new NullPointerException (); int c = ctl.get (); / / workCountOf (c) indicates the number of threads in the current thread pool Here is a judgment. When the number of threads in the thread pool is less than the number of core pools, we will call the addWorker () method to add our tasks. Later we can see that the addWorker () method actually creates threads and processes requests, similar to new Thread (xxx). Start () in this way if (workerCountOf (c))
< corePoolSize) { if (addWorker(command, true)) return; c = ctl.get(); }//如果当前线程数目大于核心线程并且任务放入一个队列成功,内部还会再次进行线程池状态判断,这里的&&用得比较精髓(短路作用),好好体会一下, 假如不是运行状态那就会执行remove方法 删除队列中的任务,如果是运行状态直接进入else if,这里的目的是线程池中已经关闭了,我们添加一个null任务 表示线程池不再处理任务 if (isRunning(c) && workQueue.offer(command)) { int recheck = ctl.get(); if (! isRunning(recheck) && remove(command)) reject(command); else if (workerCountOf(recheck) == 0) addWorker(null, false); }//能执行到这里,说明上面两个if中的条件都不满足,条件应该是:当前线程大于核心线程,并且向队列中添加任务失败,换句说说就是对列已经满了,装不下这么多任务 于是我们reject()方法内部就是对这些多余的任务进行处理的一些策略,默认就是直接丢弃 else if (!addWorker(command, false)) reject(command); } 对于面这三种情况的判断还是很清楚的,我们忽略很多细节,因为我们的目的是要对整个逻辑有个大概的了解,而不是去完全消化这些源码,这很不现实,要想理解透彻只能慢慢的去研究... 我们来看看最重要的addWorker()这个方法,这个方法就是线程池将我们传进来的new Runnable(xxx)进行处理,其实内部就是用new Thread(xxxx).start()处理,只是出于线程池中会进行很多的条件判断以及将Runnable()做进一步的封装,我们了解就好,代码如下: private boolean addWorker(Runnable firstTask, boolean core) { //这里删除很多的条件判断的代码 .......... boolean workerStarted = false; boolean workerAdded = false; Worker w = null; try { final ReentrantLock mainLock = this.mainLock; //注意下面这两行,其实就是将我们传进来的Runnable()进行封装成Worker,在Worker构造器里面会new Thread()并且保存起来 这样做的一个好处就是直接将一个线程和一个Runnable进行绑定,我们随时可以从Worker中获取线程然后调用start()方法就ok了 w = new Worker(firstTask); final Thread t = w.thread; if (t != null) { mainLock.lock(); try { //此处删除一些 ......... if (rs < SHUTDOWN || (rs == SHUTDOWN && firstTask == null)) { if (t.isAlive()) // precheck that t is startable throw new IllegalThreadStateException(); //由于会有很多个Worker,于是我们会创建HashSet workers = new HashSet(),用于保存所有的worker,后续直接遍历处理很方便 而且我们所说的线程池的本质就是这个workers,也就是一个HashSet workers.add(w); int s = workers.size(); if (s >LargestPoolSize) largestPoolSize = s; workerAdded = true;}} finally {mainLock.unlock ();} / / in the following if statement is an infinite loop of the start () method if (workerAdded) {t.start (); workerStarted = true;} return workerStarted;}
You may not believe it when you say it, but I don't understand it here, because there is always something wrong with the last start () method, but I don't know. Which run () method do you think CPU will execute when running this thread after this start () method? Is it the run () method of the class we passed in? Or the run () method of worker?
Let's take a look at the following two lines of code. The code for the new thread in the Worker constructor is not screenshot. Let's change the following lines of code:
Worker w = new Worker (firstTask); final Thread t = w. Threadist.t.start ()
After the change:
Worker w = new Worker (firstTask); / / firstTask is the class we passed in that implements the Runnable interface, but Worker also implements the Runnable interface final Thread t = getThreadFactory (). NewThread (wt.start ())
See, the run () method of Worker is actually called, and then a lot of processing is done inside the run () method of Worker, and finally the run () method that we passed in is called. 5. Summary of the personal feeling that this is enough, basically understand the process of the thread pool, of course, interested partners can continue to take a closer look at the Worker in the run () method is how to implement, in fact, relatively easy, mainly by a lot of thread pool a lot of state ah, the number of threads and other judgments may interfere with our understanding, if later we need to slowly in-depth! In fact, this article does not say much, it is to give you the roughest understanding of what the thread pool is, in fact, the essence is a HashSet, and then encapsulate the Runnable () instance we created into a Worker object, in which Worker also implements the Runnable interface, somewhat similar to the decorator pattern, ! Then save the WOrker to that collection, and then call the start () method to call the run () method of worker, and then probably call the run () method that we passed in.
Thank you for reading, the above is the content of "what are the java virtual machine multithreading knowledge points". After the study of this article, I believe you have a deeper understanding of what the java virtual machine multithreading knowledge points have, and the specific use needs to be verified in practice. Here is, the editor will push for you more related knowledge points of the article, welcome to follow!
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.