HikariCP case study 5 CopyOnWriteArrayList
Code Snapshot: Connection Borrowing Logic
Here’s a key piece of HikariCP internals when a thread tries to borrow a connection from the pool:
1 | // ② |
This code attempts to borrow a connection from the internal connectionBag
. If it doesn’t succeed within the specified timeout, it returns null
, and the calling code exits the loop and throws an exception.
Behind the Scenes: What’s connectionBag
?
The connectionBag
is a custom concurrent structure used by HikariCP to manage connections. Internally, it uses a CopyOnWriteArrayList
to store available PoolEntry
objects.
Why Use CopyOnWriteArrayList?
CopyOnWriteArrayList
is a thread-safe variant of ArrayList
where all mutative operations (like add, remove) are implemented by making a fresh copy of the underlying array. It shines in situations where:
- Reads are far more frequent than writes.
- Thread safety is critical, but locking overhead must be minimized.
This fits HikariCP’s use case perfectly—connections are borrowed and returned frequently under high concurrency, and most operations are reads (checking for available connections).
What Happens During borrow()
?
The borrow()
method performs the following steps:
- Iterates over the
CopyOnWriteArrayList
of available connections. - Tries to atomically claim one via
compareAndSet
. - If no connection is immediately available, it waits until:
- A connection is returned.
- The timeout expires.
Thanks to CopyOnWriteArrayList
, multiple threads can safely iterate and borrow connections without the risk of ConcurrentModificationException
or complex locking strategies.
Timeout Behavior
If no connection is available within the timeout window:
1 | if (poolEntry == null) { |
The system recognizes that it’s better to fail fast than to block indefinitely. This ensures predictability and avoids resource starvation under load.
Trade-offs of CopyOnWriteArrayList
While CopyOnWriteArrayList
is great for safe, lock-free reads, it does have drawbacks:
- Writes (adds/removes) are costly since the array is copied.
- It’s not ideal if the list is modified very frequently.
In HikariCP’s case, connection availability doesn’t change every millisecond—so this trade-off is acceptable and even advantageous.
Takeaways
CopyOnWriteArrayList
plays a crucial role in enabling fast, concurrent access to connection entries in HikariCP.- It ensures safety and performance without heavyweight synchronization.
- The timeout logic provides a safety net to prevent system hangs under high load.
Final Thoughts
This case study shows how a seemingly simple collection choice—like CopyOnWriteArrayList
—can dramatically influence the performance and reliability of a high-throughput system like HikariCP. It’s a perfect example of using the right tool for the job in a multithreaded environment.