Java geek

1. In this chapter

Understand the state of the pool resource and how the state changes for reference in the design of the pool resource.

2.HikariPool resource core class review

HikariPool resource classes are as follows:

Class description:

class Duties and responsibilities
HikariPool Resource pool, an entry point for client resource operations.
ConcurrentBag General purpose package and dispatch tool.
CopyOnWriteArrayList A list of storage resources, PoolEntry. Its characteristic is read without lock, write operation with lock, improve concurrency performance.
PoolEntry The resource encapsulation class, which encapsulates Connection, records the state of the resource.
Connection The real resource to use is the database connection.

3. Resource status

PoolEntry actually has two states or properties:

3.1 the state

State indicates whether a resource is available. The state changes as follows:

state When to change
Not In Use 1. During connection pool initialization

2. Release resources back to the pool

3. Lend resources, when resources are insufficient
In Use When lending available resources.
Reserved 1. When a resource exceeds its maximum life cycle

2. The resource pool is shutdown

3. Detect retrograde time

4. When the caller calls actively.
Removed 1. Connection pool initialization, dynamic scaling (down)

2. Obtain the connection

3. When a specific exception occurs.

3.1.1 the Not In Use

This state indicates that the resource is not in use, waiting to be allocated, has just been initialized or released back to the resource pool.

1. During connection pool initialization, resources in the connection pool are initialized and reach the minimum number of resources. These resources are in this state.

2. The resource status changes from In Use to Not In Use when the pool is released.

3. Lend resources. If the resources in the pool are insufficient and the number of resources in the pool does not reach the upper limit, new resources are created and their status is the same.

3.1.2 In Use

The only scenario is when a resource is lent and the resource changes from Not In Use to In Use.

3.1.3 Reserved

1. When a resource exceeds the maximum life cycle, each resource instance can be set to the maximum life cycle. If the resource instance exceeds the maximum life cycle and is Not In Use, it is changed to the Reserved state.

2. When the resource pool is shouDown, the state of the resource pool is changed from Not In Use to Reserved to prevent it from being lent out.

3.Detect retrograde time is a very special scenario, which is to check whether clock synchronization has been dialed back. This scenario is not generally considered, the reference code is as follows:

//HouseKeeper.java
            // Detect retrograde time, allowing +128ms as per NTP spec.
            if (plusMillis(now, 128) < plusMillis(previous, housekeepingPeriodMs)) {
               logger.warn("{} - Retrograde clock change detected (housekeeper delta={}), soft-evicting connections from pool.",
                           poolName, elapsedDisplayString(previous, now));
               previous = now;
               softEvictConnections();
               return;
            }
Copy the code

When a resource exceeds its maximum life cycle, it is executed by a delayed thread task. If the thread executes and the resource is not used, the maximum life cycle has been exceeded.

4. Allow callers to actively call methods to set this state. There is no direct call point in HikariPool. The code is as follows:

//HikariDataSource.java
   /**
    * Evict a connection from the pool.  If the connection has already been closed (returned to the pool)
    * this may result in a "soft" eviction; the connection will be evicted sometime in the future if it is
    * currently in use.  If the connection has not been closed, the eviction is immediate.
    *
    * @param connection the connection to evict from the pool
    */
   public void evictConnection(Connection connection)
   {
      HikariPool p;
      if(! isClosed() && (p = pool) ! =null && connection.getClass().getName().startsWith("com.zaxxer.hikari")) { p.evictConnection(connection); }}Copy the code

3.1.4 Removed

This state means that the resource is cleared from the connection pool, the database connection is actually closed, and the resource is released.

1. During connection pool initialization, the number of resources in the pool reaches the minimum number of connections and the idle time of some connections exceeds the allowed idle time. In this case, the connections are released and the number of resources in the pool decreases to the minimum number of connections.

2. To obtain a connection, usually we can not to release the connection at this time, here because when the connection pool shutdown, some connections may be set to evicted, such a connection is not available, for such a connection to release, the cause of this scenario happened this two actions have no lock, and don’t lock the purpose is to improve performance, After all, this scenario is rare and doesn’t occur most of the time, which improves performance in most cases.

3. When a specific exception occurs, the exception directly causes the database connection to be unavailable. Therefore, the database connection will be released.

3.2 evict

Another state or attribute of a resource is the EVICT flag, which, if true, means that the resource is unavailable. The state change is simple and defaults to false.



If the evICT flag of a resource is true, the resource is unavailable and the next resource is fetched.

The time when the resource becomes true can be referenced to the time when state becomes removed, which can be understood as the time when the resource becomes unavailable and will be removed.

From the changes of the above two states, it seems that evict can be replaced by the removed state as true, but it is not done in HikariPool. On the one hand, it may be because the two have different business meanings. On the other hand, EVict is still used in exception processing. Interested can look at the source code.

4. To summarize

HikariPool uses the resource state to control the availability of resources, rather than one available resource pool and one used resource pool. This has the following advantages:

  1. The control granularity is smaller and more accurate, and locks on specific resources are not needed, which conforms to the principle of reducing the lock granularity of concurrent programming optimization
  2. Scaling is easier, and adding new states, if controlled by different pools, will cause new pools to be added to record these resources.

HikariPool uses state and EVICT to control the use of resources. Whether this is necessary in the actual design should be considered according to the actual situation:

  1. From a decoupling point of view, if there are two business semantics in the business, and the different semantics have different purposes, then separate.
  2. If the actual business only needs one state, there is no need to split the state into two at the beginning, but you can follow the applicable principles and expand when necessary.

end.


<– Thanks for the triple punch, left likes and followings.


Related reading: HikariPool source code (a) first HikariPool source code (two) design ideas for reference HikariPool source code (three) resource pool dynamic scaling HikariPool source code (five) worker threads and related tools class HikariPool source code (six) to use some useful JAVA features


Java geek site: javageektour.com/