23
23
import java .sql .SQLException ;
24
24
import java .sql .Statement ;
25
25
import java .util .Properties ;
26
+ import java .util .concurrent .TimeUnit ;
27
+ import java .util .concurrent .locks .ReentrantLock ;
26
28
import java .util .logging .Logger ;
27
29
28
30
import javax .sql .DataSource ;
@@ -41,6 +43,7 @@ public class PooledDataSource implements DataSource {
41
43
private static final Log log = LogFactory .getLog (PooledDataSource .class );
42
44
43
45
private final PoolState state = new PoolState (this );
46
+ private final ReentrantLock fairLock = new ReentrantLock (true );
44
47
45
48
private final UnpooledDataSource dataSource ;
46
49
@@ -328,6 +331,7 @@ public int getPoolPingConnectionsNotUsedFor() {
328
331
* Closes all active and idle connections in the pool.
329
332
*/
330
333
public void forceCloseAll () {
334
+ fairLock .lock ();
331
335
synchronized (state ) {
332
336
expectedConnectionTypeCode = assembleConnectionTypeCode (dataSource .getUrl (), dataSource .getUsername (), dataSource .getPassword ());
333
337
for (int i = state .activeConnections .size (); i > 0 ; i --) {
@@ -374,7 +378,8 @@ private int assembleConnectionTypeCode(String url, String username, String passw
374
378
375
379
protected void pushConnection (PooledConnection conn ) throws SQLException {
376
380
377
- synchronized (state ) {
381
+ try {
382
+ fairLock .lock ();
378
383
state .activeConnections .remove (conn );
379
384
if (conn .isValid ()) {
380
385
if (state .idleConnections .size () < poolMaximumIdleConnections && conn .getConnectionTypeCode () == expectedConnectionTypeCode ) {
@@ -390,7 +395,7 @@ protected void pushConnection(PooledConnection conn) throws SQLException {
390
395
if (log .isDebugEnabled ()) {
391
396
log .debug ("Returned connection " + newConn .getRealHashCode () + " to pool." );
392
397
}
393
- state . notifyAll ();
398
+ fairLock . unlock ();
394
399
} else {
395
400
state .accumulatedCheckoutTime += conn .getCheckoutTime ();
396
401
if (!conn .getRealConnection ().getAutoCommit ()) {
@@ -408,6 +413,10 @@ protected void pushConnection(PooledConnection conn) throws SQLException {
408
413
}
409
414
state .badConnectionCount ++;
410
415
}
416
+ } finally {
417
+ if (fairLock .isLocked ()) {
418
+ fairLock .unlock ();
419
+ }
411
420
}
412
421
}
413
422
@@ -418,7 +427,8 @@ private PooledConnection popConnection(String username, String password) throws
418
427
int localBadConnectionCount = 0 ;
419
428
420
429
while (conn == null ) {
421
- synchronized (state ) {
430
+ fairLock .lock ();
431
+ try {
422
432
if (!state .idleConnections .isEmpty ()) {
423
433
// Pool has available connection
424
434
conn = state .idleConnections .remove (0 );
@@ -476,7 +486,7 @@ private PooledConnection popConnection(String username, String password) throws
476
486
log .debug ("Waiting as long as " + poolTimeToWait + " milliseconds for connection." );
477
487
}
478
488
long wt = System .currentTimeMillis ();
479
- state . wait (poolTimeToWait );
489
+ fairLock . tryLock (poolTimeToWait , TimeUnit . MILLISECONDS );
480
490
state .accumulatedWaitTime += System .currentTimeMillis () - wt ;
481
491
} catch (InterruptedException e ) {
482
492
// set interrupt flag
@@ -513,6 +523,10 @@ private PooledConnection popConnection(String username, String password) throws
513
523
}
514
524
}
515
525
}
526
+ } finally {
527
+ if (fairLock .isLocked ()) {
528
+ fairLock .unlock ();
529
+ }
516
530
}
517
531
518
532
}
0 commit comments