In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-12 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Internet Technology >
Share
Shulou(Shulou.com)06/01 Report--
This article mainly explains "how to use ConcurrentBag in HikariCP". The content in the article is simple and clear, and it is easy to learn and understand. Please follow the editor's train of thought to study and learn "how to use ConcurrentBag in HikariCP".
We know that the default connection pool for SpringBoot is HikariCP, and HikariCP is famous for its high speed, which is inseparable from ConcurrentBag.
If you look at a lot of source code, you will find that many frameworks will customize collection classes, because JDK generic collections need to take care of a lot of scenarios, and customization is definitely better than universalization.
For example, HikariCP does not use ArrayList but defines a FastList, because ArrayList has a range check every get, and the remove is traversed from front to back.
In the HikariCP scenario, every get range check is not necessary, and it is better to traverse from back to front when remove, so it is customized.
There are many optimizations for HikariCP, and in this article we will talk about one of them, that is, today's protagonist is ConcurrentBag.
But today's goal is not to analyze HikariCP, but to introduce this collection class.
Find some optimization ideas from it, like when the interviewer asks you how to design a connection pool, you can move it out: "Gee, I have an optimization idea."
ConcurrentBag
In general, the initial idea of designing a connection pool is to use locks to ensure thread safety, or to use some thread-safe concurrent containers to store connections.
HikariCP is not satisfied with this, it specially designed ConcurrentBag to store database connections, when HikariPool#getConnection is to go to ConcurrentBag to get the connection.
ConcurrentBag as a whole is a lock-free design, with three important member variables:
ThreadLocal cache to speed up local connection acquisition CopyOnWriteArrayList, copy ListSynchronousQueue while writing, and wait queue without storage
The basic process for obtaining a database connection is as follows:
When getting a connection, you will first go to ThreadLocal to find the previously used connection, and return it directly if you find the connection status is available. (ThreadLocal is a local resource, and each thread has priority to find it locally, so there is less competition and fewer connections to traverse, so it is faster.) it is impossible to find available connections in the shared write-time replication list of sharedList. If it cannot be found again, it waits for the available connection through handoffQueue, and returns null if it exceeds a certain amount of time.
In fact, this kind of thinking is very simple.
Each thread must start with an empty local resource, and then each thread stores its own used connections, and then gives priority to the stored links.
Over time, each thread will have its own local storage connection, so everyone will use their own less competition, so the speed will not be faster?
Let's take a look at the source code of the link, there are still some details.
Actually, it should be called a borrowed connection, because it needs to be returned, and it's not removing the connection from the ConcurrentBag, it's just returning a reference.
The details have been marked in the code. It is emphasized here that borrowing a connection does not remove the connection, other threads can still find the connection through sharedList, but the state of the connection is STATE_IN_USE if the connection is occupied, so that other threads will not use the connection.
The overall idea is to find it locally, and if not, go to the sharedList that every thread can access, and wait no longer.
There is also a concept of theft, in fact, there is no fancy, is to make full use of the connection.
It is nothing more than a local connection that originally belongs to a thread. When it returns the connection, another thread happens to find the connection from sharedList traversal. At this time, the state of the connection is STATE_NOT_IN_USE, and the connection will be saved to ThreadLocal by another thread.
This is stealing, and let's take a look at the code that returns the connection, where the connection is saved to the ThreadLocal.
I saw in the book "HikariCP Database connection Pool practice" that the code for returning connections looks like this in HikariCP 2.6.0.
Stop and see if there's a problem?
The thread that currently returns the connection needs to wait until the connection is taken away by another thread or when there is no waiting thread to get out of the loop.
But there will be a situation: when the connection is set to available, the connection has been borrowed by another thread, and then the current thread is still foolishly executing the loop, while the waiting thread happens to be there all the time, but every time the handoffQueue.offer is not fetched by a thread, then yield, and so on.
This makes it clear that the connection has been returned, and the returned thread still does useless spin operations, so it is optimized to the above code, if bagEntry.getState ()! = STATE_NOT_IN_USE indicates that it has been borrowed by other threads, so directly return.
Let's mention CopyOnWriteArrayList again.
Connection pooling is a typical scenario of reading more and writing less, so replication is a perfect place to write.
To put it simply: when writing, the current list will be copied to make changes, and then the old list will be replaced when the changes are finished.
The thread reading before the replacement reads the data of the old list, so that it can be read without locks.
The disadvantage of copying when writing is the memory footprint, because you need to copy a copy of the data, and if the data is large, you need to consider the amount of content.
For example, the fork operation of the operating system process will also use write-time replication. The child process and the parent process will share the data at the beginning, and will copy it when there is a change.
During the BGSAVE command or BGREWRITEAOF command of Redis, the child process is used to perform background operations, and the load factor of Redis hash table expansion becomes larger to avoid unnecessary memory write operations (capacity expansion) during fork.
Thank you for your reading, the above is the content of "how to use ConcurrentBag in HikariCP". After the study of this article, I believe you have a deeper understanding of how to use ConcurrentBag in HikariCP, 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.