Skip to content

Commit 84cc6a1

Browse files
authored
Merge pull request #2602 from why168/refactor/lock
PooledDataSource : replace synchronized block with ReentrantLock
2 parents d081405 + 9990dd7 commit 84cc6a1

File tree

1 file changed

+21
-5
lines changed

1 file changed

+21
-5
lines changed

src/main/java/org/apache/ibatis/datasource/pooled/PooledDataSource.java

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,6 +23,10 @@
2323
import java.sql.SQLException;
2424
import java.sql.Statement;
2525
import java.util.Properties;
26+
import java.util.concurrent.TimeUnit;
27+
import java.util.concurrent.locks.Condition;
28+
import java.util.concurrent.locks.Lock;
29+
import java.util.concurrent.locks.ReentrantLock;
2630
import java.util.logging.Logger;
2731

2832
import javax.sql.DataSource;
@@ -56,6 +60,9 @@ public class PooledDataSource implements DataSource {
5660

5761
private int expectedConnectionTypeCode;
5862

63+
private final Lock lock = new ReentrantLock();
64+
private final Condition condition = lock.newCondition();
65+
5966
public PooledDataSource() {
6067
dataSource = new UnpooledDataSource();
6168
}
@@ -328,7 +335,8 @@ public int getPoolPingConnectionsNotUsedFor() {
328335
* Closes all active and idle connections in the pool.
329336
*/
330337
public void forceCloseAll() {
331-
synchronized (state) {
338+
lock.lock();
339+
try {
332340
expectedConnectionTypeCode = assembleConnectionTypeCode(dataSource.getUrl(), dataSource.getUsername(), dataSource.getPassword());
333341
for (int i = state.activeConnections.size(); i > 0; i--) {
334342
try {
@@ -358,6 +366,8 @@ public void forceCloseAll() {
358366
// ignore
359367
}
360368
}
369+
} finally {
370+
lock.unlock();
361371
}
362372
if (log.isDebugEnabled()) {
363373
log.debug("PooledDataSource forcefully closed/removed all connections.");
@@ -374,7 +384,8 @@ private int assembleConnectionTypeCode(String url, String username, String passw
374384

375385
protected void pushConnection(PooledConnection conn) throws SQLException {
376386

377-
synchronized (state) {
387+
lock.lock();
388+
try {
378389
state.activeConnections.remove(conn);
379390
if (conn.isValid()) {
380391
if (state.idleConnections.size() < poolMaximumIdleConnections && conn.getConnectionTypeCode() == expectedConnectionTypeCode) {
@@ -390,7 +401,7 @@ protected void pushConnection(PooledConnection conn) throws SQLException {
390401
if (log.isDebugEnabled()) {
391402
log.debug("Returned connection " + newConn.getRealHashCode() + " to pool.");
392403
}
393-
state.notifyAll();
404+
condition.signal();
394405
} else {
395406
state.accumulatedCheckoutTime += conn.getCheckoutTime();
396407
if (!conn.getRealConnection().getAutoCommit()) {
@@ -408,6 +419,8 @@ protected void pushConnection(PooledConnection conn) throws SQLException {
408419
}
409420
state.badConnectionCount++;
410421
}
422+
} finally {
423+
lock.unlock();
411424
}
412425
}
413426

@@ -418,7 +431,8 @@ private PooledConnection popConnection(String username, String password) throws
418431
int localBadConnectionCount = 0;
419432

420433
while (conn == null) {
421-
synchronized (state) {
434+
lock.lock();
435+
try {
422436
if (!state.idleConnections.isEmpty()) {
423437
// Pool has available connection
424438
conn = state.idleConnections.remove(0);
@@ -476,7 +490,7 @@ private PooledConnection popConnection(String username, String password) throws
476490
log.debug("Waiting as long as " + poolTimeToWait + " milliseconds for connection.");
477491
}
478492
long wt = System.currentTimeMillis();
479-
state.wait(poolTimeToWait);
493+
condition.await(poolTimeToWait, TimeUnit.MILLISECONDS);
480494
state.accumulatedWaitTime += System.currentTimeMillis() - wt;
481495
} catch (InterruptedException e) {
482496
// set interrupt flag
@@ -513,6 +527,8 @@ private PooledConnection popConnection(String username, String password) throws
513527
}
514528
}
515529
}
530+
} finally {
531+
lock.unlock();
516532
}
517533

518534
}

0 commit comments

Comments
 (0)