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 .Condition ;
28
+ import java .util .concurrent .locks .Lock ;
29
+ import java .util .concurrent .locks .ReentrantLock ;
26
30
import java .util .logging .Logger ;
27
31
28
32
import javax .sql .DataSource ;
@@ -56,6 +60,9 @@ public class PooledDataSource implements DataSource {
56
60
57
61
private int expectedConnectionTypeCode ;
58
62
63
+ private final Lock lock = new ReentrantLock ();
64
+ private final Condition condition = lock .newCondition ();
65
+
59
66
public PooledDataSource () {
60
67
dataSource = new UnpooledDataSource ();
61
68
}
@@ -328,7 +335,8 @@ public int getPoolPingConnectionsNotUsedFor() {
328
335
* Closes all active and idle connections in the pool.
329
336
*/
330
337
public void forceCloseAll () {
331
- synchronized (state ) {
338
+ lock .lock ();
339
+ try {
332
340
expectedConnectionTypeCode = assembleConnectionTypeCode (dataSource .getUrl (), dataSource .getUsername (), dataSource .getPassword ());
333
341
for (int i = state .activeConnections .size (); i > 0 ; i --) {
334
342
try {
@@ -358,6 +366,8 @@ public void forceCloseAll() {
358
366
// ignore
359
367
}
360
368
}
369
+ } finally {
370
+ lock .unlock ();
361
371
}
362
372
if (log .isDebugEnabled ()) {
363
373
log .debug ("PooledDataSource forcefully closed/removed all connections." );
@@ -374,7 +384,8 @@ private int assembleConnectionTypeCode(String url, String username, String passw
374
384
375
385
protected void pushConnection (PooledConnection conn ) throws SQLException {
376
386
377
- synchronized (state ) {
387
+ lock .lock ();
388
+ try {
378
389
state .activeConnections .remove (conn );
379
390
if (conn .isValid ()) {
380
391
if (state .idleConnections .size () < poolMaximumIdleConnections && conn .getConnectionTypeCode () == expectedConnectionTypeCode ) {
@@ -390,7 +401,7 @@ protected void pushConnection(PooledConnection conn) throws SQLException {
390
401
if (log .isDebugEnabled ()) {
391
402
log .debug ("Returned connection " + newConn .getRealHashCode () + " to pool." );
392
403
}
393
- state . notifyAll ();
404
+ condition . signal ();
394
405
} else {
395
406
state .accumulatedCheckoutTime += conn .getCheckoutTime ();
396
407
if (!conn .getRealConnection ().getAutoCommit ()) {
@@ -408,6 +419,8 @@ protected void pushConnection(PooledConnection conn) throws SQLException {
408
419
}
409
420
state .badConnectionCount ++;
410
421
}
422
+ } finally {
423
+ lock .unlock ();
411
424
}
412
425
}
413
426
@@ -418,7 +431,8 @@ private PooledConnection popConnection(String username, String password) throws
418
431
int localBadConnectionCount = 0 ;
419
432
420
433
while (conn == null ) {
421
- synchronized (state ) {
434
+ lock .lock ();
435
+ try {
422
436
if (!state .idleConnections .isEmpty ()) {
423
437
// Pool has available connection
424
438
conn = state .idleConnections .remove (0 );
@@ -476,7 +490,7 @@ private PooledConnection popConnection(String username, String password) throws
476
490
log .debug ("Waiting as long as " + poolTimeToWait + " milliseconds for connection." );
477
491
}
478
492
long wt = System .currentTimeMillis ();
479
- state . wait (poolTimeToWait );
493
+ condition . await (poolTimeToWait , TimeUnit . MILLISECONDS );
480
494
state .accumulatedWaitTime += System .currentTimeMillis () - wt ;
481
495
} catch (InterruptedException e ) {
482
496
// set interrupt flag
@@ -513,6 +527,8 @@ private PooledConnection popConnection(String username, String password) throws
513
527
}
514
528
}
515
529
}
530
+ } finally {
531
+ lock .unlock ();
516
532
}
517
533
518
534
}
0 commit comments