use ReentrantLock replace sysnchronized. for ali jvm fiber wisp

This commit is contained in:
wenshao
2017-03-14 10:07:05 +08:00
parent 781f4de2b4
commit aa8459e192
6 changed files with 124 additions and 59 deletions
@@ -24,6 +24,8 @@ import java.sql.SQLException;
import java.sql.Savepoint;
import java.util.Date;
import java.util.Properties;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import com.alibaba.druid.filter.Filter;
import com.alibaba.druid.filter.FilterChain;
@@ -69,6 +71,8 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
public final static String ATTR_TRANSACTION = "stat.tx";
public final static String ATTR_RESULTSET_CLOSED = "stat.rs.closed";
private final Lock lock = new ReentrantLock();
// protected JdbcDataSourceStat dataSourceStat;
@Deprecated
@@ -151,13 +155,18 @@ public class StatFilter extends FilterEventAdapter implements StatFilterMBean {
}
@Override
public synchronized void init(DataSourceProxy dataSource) {
if (this.dbType == null || this.dbType.trim().length() == 0) {
this.dbType = dataSource.getDbType();
}
public void init(DataSourceProxy dataSource) {
lock.lock();
try {
if (this.dbType == null || this.dbType.trim().length() == 0) {
this.dbType = dataSource.getDbType();
}
configFromProperties(dataSource.getConnectProperties());
configFromProperties(System.getProperties());
configFromProperties(dataSource.getConnectProperties());
configFromProperties(System.getProperties());
} finally {
lock.unlock();
}
}
public void configFromProperties(Properties properties) {
@@ -231,6 +231,8 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
protected Condition notEmpty;
protected Condition empty;
protected ReentrantLock activeConnectionLock = new ReentrantLock();
protected AtomicLong createCount = new AtomicLong();
protected AtomicLong destroyCount = new AtomicLong();
@@ -1372,8 +1374,11 @@ public abstract class DruidAbstractDataSource extends WrapperAdapter implements
}
public Set<DruidPooledConnection> getActiveConnections() {
synchronized (activeConnections) {
activeConnectionLock.lock();
try {
return new HashSet<DruidPooledConnection>(this.activeConnections.keySet());
} finally {
activeConnectionLock.unlock();
}
}
@@ -35,6 +35,7 @@ import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.locks.ReentrantLock;
/**
* @author wenshao [szujobs@hotmail.com]
@@ -1007,7 +1007,8 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
if (realDriverClassName.equals(JdbcConstants.MYSQL_DRIVER) //
|| realDriverClassName.equals(JdbcConstants.MYSQL_DRIVER_6)) {
this.validConnectionChecker = new MySqlValidConnectionChecker();
} else if (realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER)) {
} else if (realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER)
|| realDriverClassName.equals(JdbcConstants.ORACLE_DRIVER2)) {
this.validConnectionChecker = new OracleValidConnectionChecker();
} else if (realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER)
|| realDriverClassName.equals(JdbcConstants.SQL_SERVER_DRIVER_SQLJDBC4)
@@ -1141,8 +1142,11 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
poolableConnection.setConnectedTimeNano();
poolableConnection.setTraceEnable(true);
synchronized (activeConnections) {
activeConnectionLock.lock();
try {
activeConnections.put(poolableConnection, PRESENT);
} finally {
activeConnectionLock.unlock();
}
}
@@ -1289,21 +1293,28 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
// exceptionSorter.isExceptionFatal
if (exceptionSorter != null && exceptionSorter.isExceptionFatal(sqlEx)) {
if (pooledConnection.isTraceEnable()) {
synchronized (activeConnections) {
activeConnectionLock.lock();
try {
if (pooledConnection.isTraceEnable()) {
activeConnections.remove(pooledConnection);
pooledConnection.setTraceEnable(false);
}
} finally {
activeConnectionLock.unlock();
}
}
boolean requireDiscard = false;
synchronized (pooledConnection) {
final ReentrantLock lock = pooledConnection.lock;
lock.lock();
try {
if ((!pooledConnection.isClosed()) || !pooledConnection.isDisable()) {
holder.setDiscard(true);
pooledConnection.disable(t);
requireDiscard = true;
}
} finally {
lock.unlock();
}
if (requireDiscard) {
@@ -1341,16 +1352,20 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
final Connection physicalConnection = holder.getConnection();
if (pooledConnection.isTraceEnable()) {
synchronized (activeConnections) {
Object oldInfo = null;
activeConnectionLock.lock();
try {
if (pooledConnection.isTraceEnable()) {
Object oldInfo = activeConnections.remove(pooledConnection);
if (oldInfo == null) {
if (LOG.isWarnEnabled()) {
LOG.warn("remove abandonded failed. activeConnections.size " + activeConnections.size());
}
}
oldInfo = activeConnections.remove(pooledConnection);
pooledConnection.setTraceEnable(false);
}
} finally {
activeConnectionLock.unlock();
}
if (oldInfo == null) {
if (LOG.isWarnEnabled()) {
LOG.warn("remove abandonded failed. activeConnections.size " + activeConnections.size());
}
}
}
@@ -1367,8 +1382,12 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
// reset holder, restore default settings, clear warnings
boolean isSameThread = pooledConnection.getOwnerThread() == Thread.currentThread();
if (!isSameThread) {
synchronized (pooledConnection) {
final ReentrantLock lock = pooledConnection.lock;
lock.lock();
try {
holder.reset();
} finally {
lock.unlock();
}
} else {
holder.reset();
@@ -2212,7 +2231,8 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
List<DruidPooledConnection> abandonedList = new ArrayList<DruidPooledConnection>();
synchronized (activeConnections) {
activeConnectionLock.lock();
try {
Iterator<DruidPooledConnection> iter = activeConnections.keySet().iterator();
for (; iter.hasNext();) {
@@ -2230,14 +2250,20 @@ public class DruidDataSource extends DruidAbstractDataSource implements DruidDat
abandonedList.add(pooledConnection);
}
}
} finally {
activeConnectionLock.unlock();
}
if (abandonedList.size() > 0) {
for (DruidPooledConnection pooledConnection : abandonedList) {
synchronized (pooledConnection) {
final ReentrantLock lock = pooledConnection.lock;
lock.lock();
try {
if (pooledConnection.isDisable()) {
continue;
}
} finally {
lock.unlock();
}
JdbcUtils.close(pooledConnection);
@@ -35,6 +35,8 @@ import java.util.List;
import java.util.Map;
import java.util.Properties;
import java.util.concurrent.Executor;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javax.sql.ConnectionEvent;
import javax.sql.ConnectionEventListener;
@@ -75,6 +77,8 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
private Throwable disableError = null;
public ReentrantLock lock = new ReentrantLock();
public DruidPooledConnection(DruidConnectionHolder holder){
super(holder.getConnection());
@@ -258,33 +262,38 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
this.disable = true;
}
public synchronized void syncClose() throws SQLException {
if (this.disable) {
return;
}
DruidConnectionHolder holder = this.holder;
if (holder == null) {
if (dupCloseLogEnable) {
LOG.error("dup close");
public void syncClose() throws SQLException {
lock.lock();
try {
if (this.disable) {
return;
}
return;
}
for (ConnectionEventListener listener : holder.getConnectionEventListeners()) {
listener.connectionClosed(new ConnectionEvent(this));
}
DruidConnectionHolder holder = this.holder;
if (holder == null) {
if (dupCloseLogEnable) {
LOG.error("dup close");
}
return;
}
DruidAbstractDataSource dataSource = holder.getDataSource();
List<Filter> filters = dataSource.getProxyFilters();
if (filters.size() > 0) {
FilterChainImpl filterChain = new FilterChainImpl(dataSource);
filterChain.dataSource_recycle(this);
} else {
recycle();
}
for (ConnectionEventListener listener : holder.getConnectionEventListeners()) {
listener.connectionClosed(new ConnectionEvent(this));
}
this.disable = true;
DruidAbstractDataSource dataSource = holder.getDataSource();
List<Filter> filters = dataSource.getProxyFilters();
if (filters.size() > 0) {
FilterChainImpl filterChain = new FilterChainImpl(dataSource);
filterChain.dataSource_recycle(this);
} else {
recycle();
}
this.disable = true;
} finally {
lock.unlock();
}
}
public void recycle() throws SQLException {
@@ -1106,8 +1115,11 @@ public class DruidPooledConnection extends PoolableWrapper implements javax.sql.
}
if (asyncCloseEnabled) {
synchronized (this) {
lock.lock();
try {
checkStateInternal();
} finally {
lock.unlock();
}
} else {
checkStateInternal();
@@ -23,6 +23,8 @@ import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;
import javax.management.JMException;
import javax.management.MBeanServer;
@@ -44,6 +46,8 @@ import com.alibaba.druid.util.JMXUtils;
@SuppressWarnings("rawtypes")
public class DruidDataSourceStatManager implements DruidDataSourceStatManagerMBean {
private final static Lock staticLock = new ReentrantLock();
public final static String SYS_PROP_INSTANCES = "druid.dataSources";
public final static String SYS_PROP_REGISTER_SYS_PROPERTY = "druid.registerToSysProperty";
@@ -62,23 +66,28 @@ public class DruidDataSourceStatManager implements DruidDataSourceStatManagerMBe
return instance;
}
public synchronized static void clear() {
Map<Object, ObjectName> dataSources = getInstances();
public static void clear() {
staticLock.lock();
try {
Map<Object, ObjectName> dataSources = getInstances();
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
for (Object item : dataSources.entrySet()) {
Map.Entry entry = (Map.Entry) item;
ObjectName objectName = (ObjectName) entry.getValue();
MBeanServer mbeanServer = ManagementFactory.getPlatformMBeanServer();
for (Object item : dataSources.entrySet()) {
Map.Entry entry = (Map.Entry) item;
ObjectName objectName = (ObjectName) entry.getValue();
if (objectName == null) {
continue;
}
if (objectName == null) {
continue;
}
try {
mbeanServer.unregisterMBean(objectName);
} catch (JMException e) {
LOG.error(e.getMessage(), e);
try {
mbeanServer.unregisterMBean(objectName);
} catch (JMException e) {
LOG.error(e.getMessage(), e);
}
}
} finally {
staticLock.unlock();
}
}
@@ -86,7 +95,8 @@ public class DruidDataSourceStatManager implements DruidDataSourceStatManagerMBe
public static Map<Object, ObjectName> getInstances() {
Map<Object, ObjectName> tmp = dataSources;
if (tmp == null) {
synchronized (DruidDataSourceStatManager.class) {
staticLock.lock();
try {
if (isRegisterToSystemProperty()) {
dataSources = getInstances0();
} else {
@@ -95,6 +105,8 @@ public class DruidDataSourceStatManager implements DruidDataSourceStatManagerMBe
dataSources = tmp = Collections.synchronizedMap(new IdentityHashMap<Object, ObjectName>());
}
}
} finally {
staticLock.unlock();
}
}