From c3043d8f9da6667c940c824711506433541a92c0 Mon Sep 17 00:00:00 2001 From: Brett Wooldridge Date: Mon, 22 Dec 2014 23:26:13 +0900 Subject: [PATCH] Re-use the assassin executor. --- .../java/com/zaxxer/hikari/pool/BaseHikariPool.java | 12 +++++++++--- .../main/java/com/zaxxer/hikari/pool/HikariPool.java | 11 ++++------- .../main/java/com/zaxxer/hikari/pool/HikariPool.java | 10 +++------- 3 files changed, 16 insertions(+), 17 deletions(-) diff --git a/hikaricp-common/src/main/java/com/zaxxer/hikari/pool/BaseHikariPool.java b/hikaricp-common/src/main/java/com/zaxxer/hikari/pool/BaseHikariPool.java index d2b59fea..e7147b96 100644 --- a/hikaricp-common/src/main/java/com/zaxxer/hikari/pool/BaseHikariPool.java +++ b/hikaricp-common/src/main/java/com/zaxxer/hikari/pool/BaseHikariPool.java @@ -29,6 +29,7 @@ import static com.zaxxer.hikari.util.UtilityElf.setRemoveOnCancelPolicy; import java.sql.Connection; import java.sql.SQLException; +import java.util.concurrent.ExecutorService; import java.util.concurrent.ScheduledThreadPoolExecutor; import java.util.concurrent.ThreadFactory; import java.util.concurrent.ThreadPoolExecutor; @@ -244,13 +245,17 @@ public abstract class BaseHikariPool implements HikariPoolMBean, IBagStateListen houseKeepingExecutorService.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(); do { 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.awaitTermination(5L, TimeUnit.SECONDS); 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. + * @param assassinExecutor * * @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. diff --git a/hikaricp-java6/src/main/java/com/zaxxer/hikari/pool/HikariPool.java b/hikaricp-java6/src/main/java/com/zaxxer/hikari/pool/HikariPool.java index 54f43d3f..27fc06a1 100644 --- a/hikaricp-java6/src/main/java/com/zaxxer/hikari/pool/HikariPool.java +++ b/hikaricp-java6/src/main/java/com/zaxxer/hikari/pool/HikariPool.java @@ -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_NOT_IN_USE; -import static com.zaxxer.hikari.util.UtilityElf.createThreadPoolExecutor; import static com.zaxxer.hikari.util.UtilityElf.quietlySleep; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.concurrent.ExecutorService; -import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import com.zaxxer.hikari.HikariConfig; @@ -127,6 +125,7 @@ public final class HikariPool extends BaseHikariPool * * @param connectionProxy the connection to actually close */ + @Override protected void closeConnection(final PoolBagEntry bagEntry) { bagEntry.cancelMaxLifeTermination(); @@ -150,6 +149,7 @@ public final class HikariPool extends BaseHikariPool * @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 */ + @Override protected boolean isConnectionAlive(final Connection connection, final long timeoutMs) { try { @@ -190,9 +190,9 @@ public final class HikariPool extends BaseHikariPool * * @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)) { try { bagEntry.aborted = bagEntry.evicted = true; @@ -210,9 +210,6 @@ public final class HikariPool extends BaseHikariPool } } } - - assassinExecutor.shutdown(); - assassinExecutor.awaitTermination(5L, TimeUnit.SECONDS); } /** {@inheritDoc} */ diff --git a/hikaricp/src/main/java/com/zaxxer/hikari/pool/HikariPool.java b/hikaricp/src/main/java/com/zaxxer/hikari/pool/HikariPool.java index a85a1d84..fb30e549 100644 --- a/hikaricp/src/main/java/com/zaxxer/hikari/pool/HikariPool.java +++ b/hikaricp/src/main/java/com/zaxxer/hikari/pool/HikariPool.java @@ -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_NOT_IN_USE; -import static com.zaxxer.hikari.util.UtilityElf.createThreadPoolExecutor; import static com.zaxxer.hikari.util.UtilityElf.quietlySleep; import java.sql.Connection; import java.sql.SQLException; import java.sql.Statement; import java.util.concurrent.ExecutorService; -import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; 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 * @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) { try { @@ -170,9 +169,9 @@ public final class HikariPool extends BaseHikariPool * * @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 -> { try { bagEntry.aborted = bagEntry.evicted = true; @@ -187,9 +186,6 @@ public final class HikariPool extends BaseHikariPool } } }); - - assassinExecutor.shutdown(); - assassinExecutor.awaitTermination(5L, TimeUnit.SECONDS); } /** {@inheritDoc} */