Minor cleanup

pull/333/head
Brett Wooldridge 10 years ago
parent dd095f61f2
commit ab901f544d

@ -84,7 +84,6 @@ public class HikariConfig implements HikariConfigMBean
private boolean isIsolateInternalQueries;
private boolean isRegisterMbeans;
private boolean isAllowPoolSuspension;
private boolean isWeakThreadLocals;
private DataSource dataSource;
private Properties dataSourceProperties;
private ThreadFactory threadFactory;
@ -395,28 +394,6 @@ public class HikariConfig implements HikariConfigMBean
this.isAllowPoolSuspension = isAllowPoolSuspension;
}
/**
* Get the pool ThreadLocal behavior, weak or strong references.
*
* @return true if weak reference ThreadLocals should be used
*/
public boolean isWeakThreadLocals()
{
return isWeakThreadLocals;
}
/**
* Set whether or not the pool should use weak reference ThreadLocals
* to avoid possible memory leaks in containers that undeploy/redeploy
* pool instances.
*
* @param weakThreadLocals true if weak reference ThreadLocals should be used
*/
public void setWeakThreadLocals(boolean weakThreadLocals)
{
this.isWeakThreadLocals = weakThreadLocals;
}
/**
* Get whether or not the construction of the pool should throw an exception
* if the minimum number of connections cannot be created.

@ -29,8 +29,6 @@ import javax.sql.DataSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.codahale.metrics.MetricRegistry;
import com.codahale.metrics.health.HealthCheckRegistry;
import com.zaxxer.hikari.pool.HikariPool;
import com.zaxxer.hikari.proxy.IHikariConnectionProxy;
import com.zaxxer.hikari.util.DriverDataSource;

@ -59,6 +59,7 @@ import com.zaxxer.hikari.util.ClockSource;
import com.zaxxer.hikari.util.ConcurrentBag;
import com.zaxxer.hikari.util.DefaultThreadFactory;
import com.zaxxer.hikari.util.IBagStateListener;
import com.zaxxer.hikari.util.PropertyBeanSetter;
/**
* This is the primary connection pool class that provides the basic
@ -124,7 +125,7 @@ public class HikariPool implements HikariPoolMBean, IBagStateListener
this.poolUtils = new PoolUtilities(config);
this.dataSource = poolUtils.initializeDataSource(config.getDataSourceClassName(), config.getDataSource(), config.getDataSourceProperties(), config.getDriverClassName(), config.getJdbcUrl(), username, password);
this.connectionBag = new ConcurrentBag<>(this, config.isWeakThreadLocals());
this.connectionBag = new ConcurrentBag<>(this);
this.totalConnections = new AtomicInteger();
this.connectionTimeout = config.getConnectionTimeout();
this.validationTimeout = config.getValidationTimeout();
@ -155,6 +156,9 @@ public class HikariPool implements HikariPoolMBean, IBagStateListener
poolUtils.setLoginTimeout(dataSource, connectionTimeout);
registerMBeans(config, this);
PropertyBeanSetter.flushCaches(); // prevent classloader leak
initializeConnections();
}

@ -58,7 +58,7 @@ public class ConcurrentBag<T extends IConcurrentBagEntry> implements AutoCloseab
private final AbstractQueuedLongSynchronizer synchronizer;
private final CopyOnWriteArrayList<T> sharedList;
private final boolean weakThreadLocal;
private final boolean weakThreadLocals;
private final ThreadLocal<List> threadList;
private final Sequence sequence;
@ -71,15 +71,15 @@ public class ConcurrentBag<T extends IConcurrentBagEntry> implements AutoCloseab
*
* @param listener the IBagStateListener to attach to this bag
*/
public ConcurrentBag(IBagStateListener listener, boolean weakThreadLocal)
public ConcurrentBag(IBagStateListener listener)
{
this.listener = listener;
this.weakThreadLocal = weakThreadLocal;
this.weakThreadLocals = useWeakThreadLocals();
this.sharedList = new CopyOnWriteArrayList<>();
this.synchronizer = new Synchronizer();
this.sequence = Sequence.Factory.create();
if (weakThreadLocal) {
if (weakThreadLocals) {
this.threadList = new ThreadLocal<>();
}
else {
@ -108,24 +108,14 @@ public class ConcurrentBag<T extends IConcurrentBagEntry> implements AutoCloseab
// Try the thread-local list first, if there are no blocked threads waiting already
if (!synchronizer.hasQueuedThreads()) {
List<?> list = threadList.get();
if (weakThreadLocal && list == null) {
if (weakThreadLocals && list == null) {
list = new ArrayList<>(16);
threadList.set(list);
}
for (int i = list.size() - 1; i >= 0; i--) {
final T bagEntry;
if (weakThreadLocal) {
bagEntry = (T) ((WeakReference) list.remove(i)).get();
if (bagEntry == null) {
continue;
}
}
else {
bagEntry = (T) list.remove(i);
}
if (bagEntry.state().compareAndSet(STATE_NOT_IN_USE, STATE_IN_USE)) {
final T bagEntry = (T) (weakThreadLocals ? ((WeakReference) list.remove(i)).get() : list.remove(i));
if (bagEntry != null & bagEntry.state().compareAndSet(STATE_NOT_IN_USE, STATE_IN_USE)) {
return bagEntry;
}
}
@ -177,7 +167,7 @@ public class ConcurrentBag<T extends IConcurrentBagEntry> implements AutoCloseab
if (bagEntry.state().compareAndSet(STATE_IN_USE, STATE_NOT_IN_USE)) {
final List threadLocalList = threadList.get();
if (threadLocalList != null) {
threadLocalList.add((weakThreadLocal ? new WeakReference<>(bagEntry) : bagEntry));
threadLocalList.add((weakThreadLocals ? new WeakReference<>(bagEntry) : bagEntry));
}
sequence.increment();
@ -338,6 +328,23 @@ public class ConcurrentBag<T extends IConcurrentBagEntry> implements AutoCloseab
}
}
/**
* Determine whether to use WeakReferences based on whether there is a
* custom ClassLoader implementation sitting between this class and the
* System ClassLoader.
*
* @return true if we should use WeakReferences in our ThreadLocals, false otherwise
*/
private boolean useWeakThreadLocals()
{
try {
return !(this.getClass().getClassLoader().toString().startsWith("sun.misc") || ClassLoader.getSystemClassLoader() == this.getClass().getClassLoader());
}
catch (SecurityException se) {
return true;
}
}
/**
* Our private synchronizer that handles notify/wait type semantics.
*/

@ -118,6 +118,11 @@ public final class PropertyBeanSetter
return copy;
}
public static void flushCaches()
{
Introspector.flushCaches();
}
private static void setProperty(Object target, String propName, Object propValue)
{
String capitalized = "set" + propName.substring(0, 1).toUpperCase() + propName.substring(1);

@ -56,7 +56,6 @@ public final class UtilityElf
* @param args arguments to a constructor
* @return an instance of the specified class
*/
@SuppressWarnings("unchecked")
public static <T> T createInstance(final String className, final Class<T> clazz, final Object... args)
{
if (className == null) {

@ -14,7 +14,6 @@ public class RampUpDown
HikariConfig config = new HikariConfig();
config.setMinimumIdle(5);
config.setMaximumPoolSize(60);
config.setWeakThreadLocals(true);
config.setInitializationFailFast(true);
config.setConnectionTestQuery("VALUES 1");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");

@ -50,7 +50,6 @@ public class TestConcurrentBag
config.setInitializationFailFast(true);
config.setConnectionTestQuery("VALUES 1");
config.setDataSourceClassName("com.zaxxer.hikari.mocks.StubDataSource");
config.setWeakThreadLocals(true);
ds = new HikariDataSource(config);
}
@ -100,7 +99,7 @@ public class TestConcurrentBag
}
};
}
}, false);
});
Assert.assertEquals(0, bag.values(8).size());
HikariPool pool = TestElf.getPool(ds);

Loading…
Cancel
Save