brettwooldridge / HikariCP

光 HikariCP・A solid, high-performance, JDBC connection pool at last.
Apache License 2.0
19.91k stars 2.92k forks source link

Replaced the synchronized use of `System.getProperties` with AtomicInteger in pool name generation #2115

Open echo724 opened 1 year ago

echo724 commented 1 year ago

Fix: #2104

The objective of using synchronized was to avoid overlapping in the generation of HikariPool numbers, likely in sequential operations following a call to System.getProperties. However, synchronizing these operations could potentially lead to deadlocks. Therefore, I considered an alternative that does not rely on synchronized access to the System properties. Using AtomicInteger for Pool number generation eliminates the risk of overlap without the deadlock risk associated with synchronized blocks.

  1. Reason for using AtomicInteger:  AtomicInteger serves as a JVM level shared value to handle concurrency safely while generating unique numbers within a single JVM. This ensures that each HikariConfig instance is assigned a unique pool name, even in situations where multiple threads attempt to generate pool names simultaneously.

  2. Reason for using AtomicInteger over UUID: While UUID does provide uniqueness, it comes at a higher generation cost and complexity. Conversely, using AtomicInteger allows for relatively lightweight and swift generation of unique numbers in asynchronous and concurrent environments. Furthermore, using AtomicInteger alleviates the need to handle synchronization during pool name generation, thus reducing code complexity while addressing concurrent access issues.

The generation code is as follows:

// Added priavte static field POOL_NUMBER to track pool number across the instances
private static final AtomicInteger POOL_NUMBER = new AtomicInteger(0);
...
private String generatePoolName() {
    final var prefix = "HikariPool-";
    // The pool number will be incremented atomically
    final var next = String.valueOf(poolNumber.incrementAndGet());
    return prefix + next;
}
...