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.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.

@ -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} */

@ -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} */

Loading…
Cancel
Save