Re-use the assassin executor.

2.3.0
Brett Wooldridge 10 years ago
parent 96a71da526
commit c3043d8f9d

@ -29,6 +29,7 @@ import static com.zaxxer.hikari.util.UtilityElf.setRemoveOnCancelPolicy;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadFactory;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
@ -244,13 +245,17 @@ public abstract class BaseHikariPool implements HikariPoolMBean, IBagStateListen
houseKeepingExecutorService.awaitTermination(5L, TimeUnit.SECONDS); houseKeepingExecutorService.awaitTermination(5L, TimeUnit.SECONDS);
addConnectionExecutor.awaitTermination(5L, TimeUnit.SECONDS); addConnectionExecutor.awaitTermination(5L, TimeUnit.SECONDS);
final ExecutorService assassinExecutor = createThreadPoolExecutor(configuration.getMaximumPoolSize(), "HikariCP connection assassin",
configuration.getThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
final long start = System.currentTimeMillis(); final long start = System.currentTimeMillis();
do { do {
softEvictConnections(); softEvictConnections();
abortActiveConnections(); abortActiveConnections(assassinExecutor);
} }
while ((getIdleConnections() > 0 || getActiveConnections() > 0) && elapsedTimeMs(start) < TimeUnit.SECONDS.toMillis(5)); while (getTotalConnections() > 0 && elapsedTimeMs(start) < TimeUnit.SECONDS.toMillis(5));
assassinExecutor.shutdown();
assassinExecutor.awaitTermination(5L, TimeUnit.SECONDS);
closeConnectionExecutor.shutdown(); closeConnectionExecutor.shutdown();
closeConnectionExecutor.awaitTermination(5L, TimeUnit.SECONDS); closeConnectionExecutor.awaitTermination(5L, TimeUnit.SECONDS);
logPoolState("After shutdown "); logPoolState("After shutdown ");
@ -419,10 +424,11 @@ public abstract class BaseHikariPool implements HikariPoolMBean, IBagStateListen
/** /**
* Attempt to abort() active connections on Java7+, or close() them on Java6. * Attempt to abort() active connections on Java7+, or close() them on Java6.
* @param assassinExecutor
* *
* @throws InterruptedException * @throws InterruptedException
*/ */
protected abstract void abortActiveConnections() throws InterruptedException; protected abstract void abortActiveConnections(final ExecutorService assassinExecutor) throws InterruptedException;
/** /**
* Create the JVM version-specific ConcurrentBag instance used by the pool. * Create the JVM version-specific ConcurrentBag instance used by the pool.

@ -18,14 +18,12 @@ package com.zaxxer.hikari.pool;
import static com.zaxxer.hikari.util.IConcurrentBagEntry.STATE_IN_USE; import static com.zaxxer.hikari.util.IConcurrentBagEntry.STATE_IN_USE;
import static com.zaxxer.hikari.util.IConcurrentBagEntry.STATE_NOT_IN_USE; import static com.zaxxer.hikari.util.IConcurrentBagEntry.STATE_NOT_IN_USE;
import static com.zaxxer.hikari.util.UtilityElf.createThreadPoolExecutor;
import static com.zaxxer.hikari.util.UtilityElf.quietlySleep; import static com.zaxxer.hikari.util.UtilityElf.quietlySleep;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariConfig;
@ -127,6 +125,7 @@ public final class HikariPool extends BaseHikariPool
* *
* @param connectionProxy the connection to actually close * @param connectionProxy the connection to actually close
*/ */
@Override
protected void closeConnection(final PoolBagEntry bagEntry) protected void closeConnection(final PoolBagEntry bagEntry)
{ {
bagEntry.cancelMaxLifeTermination(); bagEntry.cancelMaxLifeTermination();
@ -150,6 +149,7 @@ public final class HikariPool extends BaseHikariPool
* @param timeoutMs the timeout before we consider the test a failure * @param timeoutMs the timeout before we consider the test a failure
* @return true if the connection is alive, false if it is not alive or we timed out * @return true if the connection is alive, false if it is not alive or we timed out
*/ */
@Override
protected boolean isConnectionAlive(final Connection connection, final long timeoutMs) protected boolean isConnectionAlive(final Connection connection, final long timeoutMs)
{ {
try { try {
@ -190,9 +190,9 @@ public final class HikariPool extends BaseHikariPool
* *
* @throws InterruptedException * @throws InterruptedException
*/ */
protected void abortActiveConnections() throws InterruptedException @Override
protected void abortActiveConnections(final ExecutorService assassinExecutor) throws InterruptedException
{ {
ExecutorService assassinExecutor = createThreadPoolExecutor(configuration.getMaximumPoolSize(), "HikariCP connection assassin", configuration.getThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
for (PoolBagEntry bagEntry : connectionBag.values(STATE_IN_USE)) { for (PoolBagEntry bagEntry : connectionBag.values(STATE_IN_USE)) {
try { try {
bagEntry.aborted = bagEntry.evicted = true; bagEntry.aborted = bagEntry.evicted = true;
@ -210,9 +210,6 @@ public final class HikariPool extends BaseHikariPool
} }
} }
} }
assassinExecutor.shutdown();
assassinExecutor.awaitTermination(5L, TimeUnit.SECONDS);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */

@ -18,14 +18,12 @@ package com.zaxxer.hikari.pool;
import static com.zaxxer.hikari.util.IConcurrentBagEntry.STATE_IN_USE; import static com.zaxxer.hikari.util.IConcurrentBagEntry.STATE_IN_USE;
import static com.zaxxer.hikari.util.IConcurrentBagEntry.STATE_NOT_IN_USE; import static com.zaxxer.hikari.util.IConcurrentBagEntry.STATE_NOT_IN_USE;
import static com.zaxxer.hikari.util.UtilityElf.createThreadPoolExecutor;
import static com.zaxxer.hikari.util.UtilityElf.quietlySleep; import static com.zaxxer.hikari.util.UtilityElf.quietlySleep;
import java.sql.Connection; import java.sql.Connection;
import java.sql.SQLException; import java.sql.SQLException;
import java.sql.Statement; import java.sql.Statement;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import com.zaxxer.hikari.HikariConfig; import com.zaxxer.hikari.HikariConfig;
@ -134,6 +132,7 @@ public final class HikariPool extends BaseHikariPool
* @param timeoutMs the timeout before we consider the test a failure * @param timeoutMs the timeout before we consider the test a failure
* @return true if the connection is alive, false if it is not alive or we timed out * @return true if the connection is alive, false if it is not alive or we timed out
*/ */
@Override
protected boolean isConnectionAlive(final Connection connection, final long timeoutMs) protected boolean isConnectionAlive(final Connection connection, final long timeoutMs)
{ {
try { try {
@ -170,9 +169,9 @@ public final class HikariPool extends BaseHikariPool
* *
* @throws InterruptedException * @throws InterruptedException
*/ */
protected void abortActiveConnections() throws InterruptedException @Override
protected void abortActiveConnections(final ExecutorService assassinExecutor) throws InterruptedException
{ {
ExecutorService assassinExecutor = createThreadPoolExecutor(configuration.getMaximumPoolSize(), "HikariCP connection assassin", configuration.getThreadFactory(), new ThreadPoolExecutor.CallerRunsPolicy());
connectionBag.values(STATE_IN_USE).stream().forEach(bagEntry -> { connectionBag.values(STATE_IN_USE).stream().forEach(bagEntry -> {
try { try {
bagEntry.aborted = bagEntry.evicted = true; bagEntry.aborted = bagEntry.evicted = true;
@ -187,9 +186,6 @@ public final class HikariPool extends BaseHikariPool
} }
} }
}); });
assassinExecutor.shutdown();
assassinExecutor.awaitTermination(5L, TimeUnit.SECONDS);
} }
/** {@inheritDoc} */ /** {@inheritDoc} */

Loading…
Cancel
Save