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
2
3
4
5
6
7
8
// ②
// Get a connection from the pool, with a timeout
final PoolEntry poolEntry = connectionBag.borrow(timeout, MILLISECONDS);

// The borrow method returns null only if it times out
if (poolEntry == null) {
break; // We timed out... break and throw exception
}

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:

  1. Iterates over the CopyOnWriteArrayList of available connections.
  2. Tries to atomically claim one via compareAndSet.
  3. 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
2
3
if (poolEntry == null) {
break; // We timed out... break and throw exception
}

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.

Author

Elliot

Posted on

2024-04-19

Updated on

2025-04-18

Licensed under