1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 package org.apache.commons.pool2;
18
19 import java.util.Collection;
20 import java.util.Collections;
21 import java.util.HashMap;
22 import java.util.Iterator;
23 import java.util.List;
24 import java.util.Map;
25 import java.util.Timer;
26 import java.util.TimerTask;
27 import java.util.concurrent.locks.ReentrantReadWriteLock;
28 import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
29 import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;
30
31
32
33
34
35
36
37 public final class PoolUtils {
38
39
40
41
42
43
44
45
46
47
48
49 private static final class ErodingFactor {
50
51 private final float factor;
52
53
54 private transient volatile long nextShrinkMillis;
55
56
57 private transient volatile int idleHighWaterMark;
58
59
60
61
62
63
64
65 public ErodingFactor(final float factor) {
66 this.factor = factor;
67 nextShrinkMillis = System.currentTimeMillis() + (long) (900000 * factor);
68 idleHighWaterMark = 1;
69 }
70
71
72
73
74
75
76 public long getNextShrink() {
77 return nextShrinkMillis;
78 }
79
80
81
82
83 @Override
84 public String toString() {
85 return "ErodingFactor{" + "factor=" + factor +
86 ", idleHighWaterMark=" + idleHighWaterMark + '}';
87 }
88
89
90
91
92
93
94
95
96
97 public void update(final long nowMillis, final int numIdle) {
98 final int idle = Math.max(0, numIdle);
99 idleHighWaterMark = Math.max(idle, idleHighWaterMark);
100 final float maxInterval = 15f;
101 final float minutes = maxInterval +
102 (1f - maxInterval) / idleHighWaterMark * idle;
103 nextShrinkMillis = nowMillis + (long) (minutes * 60000f * factor);
104 }
105 }
106
107
108
109
110
111
112
113
114 private static class ErodingKeyedObjectPool<K, V> implements KeyedObjectPool<K, V> {
115
116
117 private final KeyedObjectPool<K, V> keyedPool;
118
119
120 private final ErodingFactor erodingFactor;
121
122
123
124
125
126
127
128
129
130
131
132
133 protected ErodingKeyedObjectPool(final KeyedObjectPool<K, V> keyedPool,
134 final ErodingFactor erodingFactor) {
135 if (keyedPool == null) {
136 throw new IllegalArgumentException(
137 MSG_NULL_KEYED_POOL);
138 }
139 this.keyedPool = keyedPool;
140 this.erodingFactor = erodingFactor;
141 }
142
143
144
145
146
147
148
149
150
151
152
153
154 public ErodingKeyedObjectPool(final KeyedObjectPool<K, V> keyedPool,
155 final float factor) {
156 this(keyedPool, new ErodingFactor(factor));
157 }
158
159
160
161
162 @Override
163 public void addObject(final K key) throws Exception {
164 keyedPool.addObject(key);
165 }
166
167
168
169
170 @Override
171 public V borrowObject(final K key) throws Exception {
172 return keyedPool.borrowObject(key);
173 }
174
175
176
177
178 @Override
179 public void clear() throws Exception {
180 keyedPool.clear();
181 }
182
183
184
185
186 @Override
187 public void clear(final K key) throws Exception {
188 keyedPool.clear(key);
189 }
190
191
192
193
194 @Override
195 public void close() {
196 try {
197 keyedPool.close();
198 } catch (final Exception ignored) {
199
200 }
201 }
202
203
204
205
206
207
208
209
210 protected ErodingFactor getErodingFactor(final K key) {
211 return erodingFactor;
212 }
213
214
215
216
217
218
219 protected KeyedObjectPool<K, V> getKeyedPool() {
220 return keyedPool;
221 }
222
223
224
225
226 @Override
227 public List<K> getKeys() {
228 return keyedPool.getKeys();
229 }
230
231
232
233
234 @Override
235 public int getNumActive() {
236 return keyedPool.getNumActive();
237 }
238
239
240
241
242 @Override
243 public int getNumActive(final K key) {
244 return keyedPool.getNumActive(key);
245 }
246
247
248
249
250 @Override
251 public int getNumIdle() {
252 return keyedPool.getNumIdle();
253 }
254
255
256
257
258 @Override
259 public int getNumIdle(final K key) {
260 return keyedPool.getNumIdle(key);
261 }
262
263
264
265
266 @Override
267 public void invalidateObject(final K key, final V obj) {
268 try {
269 keyedPool.invalidateObject(key, obj);
270 } catch (final Exception ignored) {
271
272 }
273 }
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288 @Override
289 public void returnObject(final K key, final V obj) throws Exception {
290 boolean discard = false;
291 final long nowMillis = System.currentTimeMillis();
292 final ErodingFactor factor = getErodingFactor(key);
293 synchronized (keyedPool) {
294 if (factor.getNextShrink() < nowMillis) {
295 final int numIdle = getNumIdle(key);
296 if (numIdle > 0) {
297 discard = true;
298 }
299
300 factor.update(nowMillis, numIdle);
301 }
302 }
303 try {
304 if (discard) {
305 keyedPool.invalidateObject(key, obj);
306 } else {
307 keyedPool.returnObject(key, obj);
308 }
309 } catch (final Exception ignored) {
310
311 }
312 }
313
314
315
316
317 @Override
318 public String toString() {
319 return "ErodingKeyedObjectPool{" + "factor=" +
320 erodingFactor + ", keyedPool=" + keyedPool + '}';
321 }
322 }
323
324
325
326
327
328
329
330
331
332 private static class ErodingObjectPool<T> implements ObjectPool<T> {
333
334
335 private final ObjectPool<T> pool;
336
337
338 private final ErodingFactor factor;
339
340
341
342
343
344
345
346
347
348
349
350
351 public ErodingObjectPool(final ObjectPool<T> pool, final float factor) {
352 this.pool = pool;
353 this.factor = new ErodingFactor(factor);
354 }
355
356
357
358
359 @Override
360 public void addObject() throws Exception{
361 pool.addObject();
362 }
363
364
365
366
367 @Override
368 public T borrowObject() throws Exception {
369 return pool.borrowObject();
370 }
371
372
373
374
375 @Override
376 public void clear() throws Exception {
377 pool.clear();
378 }
379
380
381
382
383 @Override
384 public void close() {
385 try {
386 pool.close();
387 } catch (final Exception ignored) {
388
389 }
390 }
391
392
393
394
395 @Override
396 public int getNumActive() {
397 return pool.getNumActive();
398 }
399
400
401
402
403 @Override
404 public int getNumIdle() {
405 return pool.getNumIdle();
406 }
407
408
409
410
411 @Override
412 public void invalidateObject(final T obj) {
413 try {
414 pool.invalidateObject(obj);
415 } catch (final Exception ignored) {
416
417 }
418 }
419
420
421
422
423
424
425
426
427
428
429
430
431 @Override
432 public void returnObject(final T obj) {
433 boolean discard = false;
434 final long nowMillis = System.currentTimeMillis();
435 synchronized (pool) {
436 if (factor.getNextShrink() < nowMillis) {
437
438 final int numIdle = pool.getNumIdle();
439 if (numIdle > 0) {
440 discard = true;
441 }
442
443 factor.update(nowMillis, numIdle);
444 }
445 }
446 try {
447 if (discard) {
448 pool.invalidateObject(obj);
449 } else {
450 pool.returnObject(obj);
451 }
452 } catch (final Exception ignored) {
453
454 }
455 }
456
457
458
459
460 @Override
461 public String toString() {
462 return "ErodingObjectPool{" + "factor=" + factor + ", pool=" +
463 pool + '}';
464 }
465 }
466
467
468
469
470
471
472
473
474 private static final class ErodingPerKeyKeyedObjectPool<K, V> extends ErodingKeyedObjectPool<K, V> {
475
476
477 private final float factor;
478
479
480 private final Map<K, ErodingFactor> factors = Collections.synchronizedMap(new HashMap<>());
481
482
483
484
485
486
487
488
489
490
491 public ErodingPerKeyKeyedObjectPool(final KeyedObjectPool<K, V> keyedPool, final float factor) {
492 super(keyedPool, null);
493 this.factor = factor;
494 }
495
496
497
498
499 @Override
500 protected ErodingFactor getErodingFactor(final K key) {
501
502
503 return factors.computeIfAbsent(key, k -> new ErodingFactor(this.factor));
504 }
505
506
507
508
509 @SuppressWarnings("resource")
510 @Override
511 public String toString() {
512 return "ErodingPerKeyKeyedObjectPool{" + "factor=" + factor +
513 ", keyedPool=" + getKeyedPool() + '}';
514 }
515 }
516
517
518
519
520
521
522
523
524 private static final class KeyedObjectPoolMinIdleTimerTask<K, V> extends TimerTask {
525
526
527 private final int minIdle;
528
529
530 private final K key;
531
532
533 private final KeyedObjectPool<K, V> keyedPool;
534
535
536
537
538
539
540
541
542
543
544
545
546
547 KeyedObjectPoolMinIdleTimerTask(final KeyedObjectPool<K, V> keyedPool,
548 final K key, final int minIdle) throws IllegalArgumentException {
549 if (keyedPool == null) {
550 throw new IllegalArgumentException(
551 MSG_NULL_KEYED_POOL);
552 }
553 this.keyedPool = keyedPool;
554 this.key = key;
555 this.minIdle = minIdle;
556 }
557
558
559
560
561 @Override
562 public void run() {
563 boolean success = false;
564 try {
565 if (keyedPool.getNumIdle(key) < minIdle) {
566 keyedPool.addObject(key);
567 }
568 success = true;
569
570 } catch (final Exception e) {
571 cancel();
572
573 } finally {
574
575 if (!success) {
576 cancel();
577 }
578 }
579 }
580
581
582
583
584 @Override
585 public String toString() {
586 final StringBuilder sb = new StringBuilder();
587 sb.append("KeyedObjectPoolMinIdleTimerTask");
588 sb.append("{minIdle=").append(minIdle);
589 sb.append(", key=").append(key);
590 sb.append(", keyedPool=").append(keyedPool);
591 sb.append('}');
592 return sb.toString();
593 }
594 }
595
596
597
598
599
600
601
602
603 private static final class ObjectPoolMinIdleTimerTask<T> extends TimerTask {
604
605
606 private final int minIdle;
607
608
609 private final ObjectPool<T> pool;
610
611
612
613
614
615
616
617
618
619
620
621
622 ObjectPoolMinIdleTimerTask(final ObjectPool<T> pool, final int minIdle)
623 throws IllegalArgumentException {
624 if (pool == null) {
625 throw new IllegalArgumentException(MSG_NULL_POOL);
626 }
627 this.pool = pool;
628 this.minIdle = minIdle;
629 }
630
631
632
633
634 @Override
635 public void run() {
636 boolean success = false;
637 try {
638 if (pool.getNumIdle() < minIdle) {
639 pool.addObject();
640 }
641 success = true;
642
643 } catch (final Exception e) {
644 cancel();
645 } finally {
646
647 if (!success) {
648 cancel();
649 }
650 }
651 }
652
653
654
655
656 @Override
657 public String toString() {
658 final StringBuilder sb = new StringBuilder();
659 sb.append("ObjectPoolMinIdleTimerTask");
660 sb.append("{minIdle=").append(minIdle);
661 sb.append(", pool=").append(pool);
662 sb.append('}');
663 return sb.toString();
664 }
665 }
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682 static final class SynchronizedKeyedObjectPool<K, V> implements KeyedObjectPool<K, V> {
683
684
685
686
687
688 private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
689
690
691 private final KeyedObjectPool<K, V> keyedPool;
692
693
694
695
696
697
698
699
700
701 SynchronizedKeyedObjectPool(final KeyedObjectPool<K, V> keyedPool)
702 throws IllegalArgumentException {
703 if (keyedPool == null) {
704 throw new IllegalArgumentException(
705 MSG_NULL_KEYED_POOL);
706 }
707 this.keyedPool = keyedPool;
708 }
709
710
711
712
713 @Override
714 public void addObject(final K key) throws Exception {
715 final WriteLock writeLock = readWriteLock.writeLock();
716 writeLock.lock();
717 try {
718 keyedPool.addObject(key);
719 } finally {
720 writeLock.unlock();
721 }
722 }
723
724
725
726
727 @Override
728 public V borrowObject(final K key) throws Exception {
729 final WriteLock writeLock = readWriteLock.writeLock();
730 writeLock.lock();
731 try {
732 return keyedPool.borrowObject(key);
733 } finally {
734 writeLock.unlock();
735 }
736 }
737
738
739
740
741 @Override
742 public void clear() throws Exception {
743 final WriteLock writeLock = readWriteLock.writeLock();
744 writeLock.lock();
745 try {
746 keyedPool.clear();
747 } finally {
748 writeLock.unlock();
749 }
750 }
751
752
753
754
755 @Override
756 public void clear(final K key) throws Exception {
757 final WriteLock writeLock = readWriteLock.writeLock();
758 writeLock.lock();
759 try {
760 keyedPool.clear(key);
761 } finally {
762 writeLock.unlock();
763 }
764 }
765
766
767
768
769 @Override
770 public void close() {
771 final WriteLock writeLock = readWriteLock.writeLock();
772 writeLock.lock();
773 try {
774 keyedPool.close();
775 } catch (final Exception ignored) {
776
777 } finally {
778 writeLock.unlock();
779 }
780 }
781
782
783
784
785 @Override
786 public List<K> getKeys() {
787 final ReadLock readLock = readWriteLock.readLock();
788 readLock.lock();
789 try {
790 return keyedPool.getKeys();
791 } finally {
792 readLock.unlock();
793 }
794 }
795
796
797
798
799 @Override
800 public int getNumActive() {
801 final ReadLock readLock = readWriteLock.readLock();
802 readLock.lock();
803 try {
804 return keyedPool.getNumActive();
805 } finally {
806 readLock.unlock();
807 }
808 }
809
810
811
812
813 @Override
814 public int getNumActive(final K key) {
815 final ReadLock readLock = readWriteLock.readLock();
816 readLock.lock();
817 try {
818 return keyedPool.getNumActive(key);
819 } finally {
820 readLock.unlock();
821 }
822 }
823
824
825
826
827 @Override
828 public int getNumIdle() {
829 final ReadLock readLock = readWriteLock.readLock();
830 readLock.lock();
831 try {
832 return keyedPool.getNumIdle();
833 } finally {
834 readLock.unlock();
835 }
836 }
837
838
839
840
841 @Override
842 public int getNumIdle(final K key) {
843 final ReadLock readLock = readWriteLock.readLock();
844 readLock.lock();
845 try {
846 return keyedPool.getNumIdle(key);
847 } finally {
848 readLock.unlock();
849 }
850 }
851
852
853
854
855 @Override
856 public void invalidateObject(final K key, final V obj) {
857 final WriteLock writeLock = readWriteLock.writeLock();
858 writeLock.lock();
859 try {
860 keyedPool.invalidateObject(key, obj);
861 } catch (final Exception ignored) {
862
863 } finally {
864 writeLock.unlock();
865 }
866 }
867
868
869
870
871 @Override
872 public void returnObject(final K key, final V obj) {
873 final WriteLock writeLock = readWriteLock.writeLock();
874 writeLock.lock();
875 try {
876 keyedPool.returnObject(key, obj);
877 } catch (final Exception ignored) {
878
879 } finally {
880 writeLock.unlock();
881 }
882 }
883
884
885
886
887 @Override
888 public String toString() {
889 final StringBuilder sb = new StringBuilder();
890 sb.append("SynchronizedKeyedObjectPool");
891 sb.append("{keyedPool=").append(keyedPool);
892 sb.append('}');
893 return sb.toString();
894 }
895 }
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910 private static final class SynchronizedKeyedPooledObjectFactory<K, V> implements KeyedPooledObjectFactory<K, V> {
911
912
913 private final WriteLock writeLock = new ReentrantReadWriteLock().writeLock();
914
915
916 private final KeyedPooledObjectFactory<K, V> keyedFactory;
917
918
919
920
921
922
923
924
925
926
927 SynchronizedKeyedPooledObjectFactory(final KeyedPooledObjectFactory<K, V> keyedFactory) throws IllegalArgumentException {
928 if (keyedFactory == null) {
929 throw new IllegalArgumentException(
930 "keyedFactory must not be null.");
931 }
932 this.keyedFactory = keyedFactory;
933 }
934
935
936
937
938 @Override
939 public void activateObject(final K key, final PooledObject<V> p) throws Exception {
940 writeLock.lock();
941 try {
942 keyedFactory.activateObject(key, p);
943 } finally {
944 writeLock.unlock();
945 }
946 }
947
948
949
950
951 @Override
952 public void destroyObject(final K key, final PooledObject<V> p) throws Exception {
953 writeLock.lock();
954 try {
955 keyedFactory.destroyObject(key, p);
956 } finally {
957 writeLock.unlock();
958 }
959 }
960
961
962
963
964 @Override
965 public PooledObject<V> makeObject(final K key) throws Exception {
966 writeLock.lock();
967 try {
968 return keyedFactory.makeObject(key);
969 } finally {
970 writeLock.unlock();
971 }
972 }
973
974
975
976
977 @Override
978 public void passivateObject(final K key, final PooledObject<V> p) throws Exception {
979 writeLock.lock();
980 try {
981 keyedFactory.passivateObject(key, p);
982 } finally {
983 writeLock.unlock();
984 }
985 }
986
987
988
989
990 @Override
991 public String toString() {
992 final StringBuilder sb = new StringBuilder();
993 sb.append("SynchronizedKeyedPooledObjectFactory");
994 sb.append("{keyedFactory=").append(keyedFactory);
995 sb.append('}');
996 return sb.toString();
997 }
998
999
1000
1001
1002 @Override
1003 public boolean validateObject(final K key, final PooledObject<V> p) {
1004 writeLock.lock();
1005 try {
1006 return keyedFactory.validateObject(key, p);
1007 } finally {
1008 writeLock.unlock();
1009 }
1010 }
1011 }
1012
1013
1014
1015
1016
1017
1018
1019
1020
1021
1022
1023
1024
1025
1026
1027
1028 private static final class SynchronizedObjectPool<T> implements ObjectPool<T> {
1029
1030
1031
1032
1033
1034 private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();
1035
1036
1037 private final ObjectPool<T> pool;
1038
1039
1040
1041
1042
1043
1044
1045
1046
1047
1048 SynchronizedObjectPool(final ObjectPool<T> pool)
1049 throws IllegalArgumentException {
1050 if (pool == null) {
1051 throw new IllegalArgumentException(MSG_NULL_POOL);
1052 }
1053 this.pool = pool;
1054 }
1055
1056
1057
1058
1059 @Override
1060 public void addObject() throws Exception {
1061 final WriteLock writeLock = readWriteLock.writeLock();
1062 writeLock.lock();
1063 try {
1064 pool.addObject();
1065 } finally {
1066 writeLock.unlock();
1067 }
1068 }
1069
1070
1071
1072
1073 @Override
1074 public T borrowObject() throws Exception {
1075 final WriteLock writeLock = readWriteLock.writeLock();
1076 writeLock.lock();
1077 try {
1078 return pool.borrowObject();
1079 } finally {
1080 writeLock.unlock();
1081 }
1082 }
1083
1084
1085
1086
1087 @Override
1088 public void clear() throws Exception {
1089 final WriteLock writeLock = readWriteLock.writeLock();
1090 writeLock.lock();
1091 try {
1092 pool.clear();
1093 } finally {
1094 writeLock.unlock();
1095 }
1096 }
1097
1098
1099
1100
1101 @Override
1102 public void close() {
1103 final WriteLock writeLock = readWriteLock.writeLock();
1104 writeLock.lock();
1105 try {
1106 pool.close();
1107 } catch (final Exception ignored) {
1108
1109 } finally {
1110 writeLock.unlock();
1111 }
1112 }
1113
1114
1115
1116
1117 @Override
1118 public int getNumActive() {
1119 final ReadLock readLock = readWriteLock.readLock();
1120 readLock.lock();
1121 try {
1122 return pool.getNumActive();
1123 } finally {
1124 readLock.unlock();
1125 }
1126 }
1127
1128
1129
1130
1131 @Override
1132 public int getNumIdle() {
1133 final ReadLock readLock = readWriteLock.readLock();
1134 readLock.lock();
1135 try {
1136 return pool.getNumIdle();
1137 } finally {
1138 readLock.unlock();
1139 }
1140 }
1141
1142
1143
1144
1145 @Override
1146 public void invalidateObject(final T obj) {
1147 final WriteLock writeLock = readWriteLock.writeLock();
1148 writeLock.lock();
1149 try {
1150 pool.invalidateObject(obj);
1151 } catch (final Exception ignored) {
1152
1153 } finally {
1154 writeLock.unlock();
1155 }
1156 }
1157
1158
1159
1160
1161 @Override
1162 public void returnObject(final T obj) {
1163 final WriteLock writeLock = readWriteLock.writeLock();
1164 writeLock.lock();
1165 try {
1166 pool.returnObject(obj);
1167 } catch (final Exception ignored) {
1168
1169 } finally {
1170 writeLock.unlock();
1171 }
1172 }
1173
1174
1175
1176
1177 @Override
1178 public String toString() {
1179 final StringBuilder sb = new StringBuilder();
1180 sb.append("SynchronizedObjectPool");
1181 sb.append("{pool=").append(pool);
1182 sb.append('}');
1183 return sb.toString();
1184 }
1185 }
1186
1187
1188
1189
1190
1191
1192
1193
1194
1195
1196
1197
1198
1199 private static final class SynchronizedPooledObjectFactory<T> implements
1200 PooledObjectFactory<T> {
1201
1202
1203 private final WriteLock writeLock = new ReentrantReadWriteLock().writeLock();
1204
1205
1206 private final PooledObjectFactory<T> factory;
1207
1208
1209
1210
1211
1212
1213
1214
1215
1216
1217 SynchronizedPooledObjectFactory(final PooledObjectFactory<T> factory)
1218 throws IllegalArgumentException {
1219 if (factory == null) {
1220 throw new IllegalArgumentException("factory must not be null.");
1221 }
1222 this.factory = factory;
1223 }
1224
1225
1226
1227
1228 @Override
1229 public void activateObject(final PooledObject<T> p) throws Exception {
1230 writeLock.lock();
1231 try {
1232 factory.activateObject(p);
1233 } finally {
1234 writeLock.unlock();
1235 }
1236 }
1237
1238
1239
1240
1241 @Override
1242 public void destroyObject(final PooledObject<T> p) throws Exception {
1243 writeLock.lock();
1244 try {
1245 factory.destroyObject(p);
1246 } finally {
1247 writeLock.unlock();
1248 }
1249 }
1250
1251
1252
1253
1254 @Override
1255 public PooledObject<T> makeObject() throws Exception {
1256 writeLock.lock();
1257 try {
1258 return factory.makeObject();
1259 } finally {
1260 writeLock.unlock();
1261 }
1262 }
1263
1264
1265
1266
1267 @Override
1268 public void passivateObject(final PooledObject<T> p) throws Exception {
1269 writeLock.lock();
1270 try {
1271 factory.passivateObject(p);
1272 } finally {
1273 writeLock.unlock();
1274 }
1275 }
1276
1277
1278
1279
1280 @Override
1281 public String toString() {
1282 final StringBuilder sb = new StringBuilder();
1283 sb.append("SynchronizedPoolableObjectFactory");
1284 sb.append("{factory=").append(factory);
1285 sb.append('}');
1286 return sb.toString();
1287 }
1288
1289
1290
1291
1292 @Override
1293 public boolean validateObject(final PooledObject<T> p) {
1294 writeLock.lock();
1295 try {
1296 return factory.validateObject(p);
1297 } finally {
1298 writeLock.unlock();
1299 }
1300 }
1301 }
1302
1303
1304
1305
1306
1307 static class TimerHolder {
1308 static final Timer MIN_IDLE_TIMER = new Timer(true);
1309 }
1310
1311 private static final String MSG_FACTOR_NEGATIVE = "factor must be positive.";
1312
1313 private static final String MSG_MIN_IDLE = "minIdle must be non-negative.";
1314
1315 static final String MSG_NULL_KEY = "key must not be null.";
1316
1317 private static final String MSG_NULL_KEYED_POOL = "keyedPool must not be null.";
1318
1319 static final String MSG_NULL_KEYS = "keys must not be null.";
1320
1321 private static final String MSG_NULL_POOL = "pool must not be null.";
1322
1323
1324
1325
1326
1327
1328
1329
1330
1331
1332
1333
1334
1335
1336
1337
1338
1339
1340
1341
1342
1343
1344
1345
1346
1347
1348
1349
1350 public static <K, V> Map<K, TimerTask> checkMinIdle(
1351 final KeyedObjectPool<K, V> keyedPool, final Collection<K> keys,
1352 final int minIdle, final long periodMillis)
1353 throws IllegalArgumentException {
1354 if (keys == null) {
1355 throw new IllegalArgumentException(MSG_NULL_KEYS);
1356 }
1357 final Map<K, TimerTask> tasks = new HashMap<>(keys.size());
1358 final Iterator<K> iter = keys.iterator();
1359 while (iter.hasNext()) {
1360 final K key = iter.next();
1361 final TimerTask task = checkMinIdle(keyedPool, key, minIdle, periodMillis);
1362 tasks.put(key, task);
1363 }
1364 return tasks;
1365 }
1366
1367
1368
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379
1380
1381
1382
1383
1384
1385
1386
1387
1388
1389
1390
1391
1392
1393 public static <K, V> TimerTask checkMinIdle(
1394 final KeyedObjectPool<K, V> keyedPool, final K key,
1395 final int minIdle, final long periodMillis)
1396 throws IllegalArgumentException {
1397 if (keyedPool == null) {
1398 throw new IllegalArgumentException(MSG_NULL_KEYED_POOL);
1399 }
1400 if (key == null) {
1401 throw new IllegalArgumentException(MSG_NULL_KEY);
1402 }
1403 if (minIdle < 0) {
1404 throw new IllegalArgumentException(MSG_MIN_IDLE);
1405 }
1406 final TimerTask task = new KeyedObjectPoolMinIdleTimerTask<>(
1407 keyedPool, key, minIdle);
1408 getMinIdleTimer().schedule(task, 0L, periodMillis);
1409 return task;
1410 }
1411
1412
1413
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1425
1426
1427
1428
1429
1430
1431
1432
1433
1434 public static <T> TimerTask checkMinIdle(final ObjectPool<T> pool,
1435 final int minIdle, final long periodMillis)
1436 throws IllegalArgumentException {
1437 if (pool == null) {
1438 throw new IllegalArgumentException(MSG_NULL_KEYED_POOL);
1439 }
1440 if (minIdle < 0) {
1441 throw new IllegalArgumentException(MSG_MIN_IDLE);
1442 }
1443 final TimerTask task = new ObjectPoolMinIdleTimerTask<>(pool, minIdle);
1444 getMinIdleTimer().schedule(task, 0L, periodMillis);
1445 return task;
1446 }
1447
1448
1449
1450
1451
1452
1453
1454
1455
1456
1457
1458
1459
1460
1461 public static void checkRethrow(final Throwable t) {
1462 if (t instanceof ThreadDeath) {
1463 throw (ThreadDeath) t;
1464 }
1465 if (t instanceof VirtualMachineError) {
1466 throw (VirtualMachineError) t;
1467 }
1468
1469 }
1470
1471
1472
1473
1474
1475
1476
1477
1478
1479
1480
1481
1482
1483
1484
1485
1486
1487
1488
1489
1490
1491 public static <K, V> KeyedObjectPool<K, V> erodingPool(final KeyedObjectPool<K, V> keyedPool) {
1492 return erodingPool(keyedPool, 1f);
1493 }
1494
1495
1496
1497
1498
1499
1500
1501
1502
1503
1504
1505
1506
1507
1508
1509
1510
1511
1512
1513
1514
1515
1516
1517
1518
1519
1520
1521
1522
1523
1524
1525
1526 public static <K, V> KeyedObjectPool<K, V> erodingPool(final KeyedObjectPool<K, V> keyedPool, final float factor) {
1527 return erodingPool(keyedPool, factor, false);
1528 }
1529
1530
1531
1532
1533
1534
1535
1536
1537
1538
1539
1540
1541
1542
1543
1544
1545
1546
1547
1548
1549
1550
1551
1552
1553
1554
1555
1556
1557
1558
1559
1560
1561
1562
1563
1564
1565
1566
1567
1568
1569
1570 public static <K, V> KeyedObjectPool<K, V> erodingPool(
1571 final KeyedObjectPool<K, V> keyedPool, final float factor,
1572 final boolean perKey) {
1573 if (keyedPool == null) {
1574 throw new IllegalArgumentException(MSG_NULL_KEYED_POOL);
1575 }
1576 if (factor <= 0f) {
1577 throw new IllegalArgumentException(MSG_FACTOR_NEGATIVE);
1578 }
1579 if (perKey) {
1580 return new ErodingPerKeyKeyedObjectPool<>(keyedPool, factor);
1581 }
1582 return new ErodingKeyedObjectPool<>(keyedPool, factor);
1583 }
1584
1585
1586
1587
1588
1589
1590
1591
1592
1593
1594
1595
1596
1597
1598
1599
1600
1601
1602
1603 public static <T> ObjectPool<T> erodingPool(final ObjectPool<T> pool) {
1604 return erodingPool(pool, 1f);
1605 }
1606
1607
1608
1609
1610
1611
1612
1613
1614
1615
1616
1617
1618
1619
1620
1621
1622
1623
1624
1625
1626
1627
1628
1629
1630
1631
1632
1633
1634
1635
1636
1637 public static <T> ObjectPool<T> erodingPool(final ObjectPool<T> pool, final float factor) {
1638 if (pool == null) {
1639 throw new IllegalArgumentException(MSG_NULL_POOL);
1640 }
1641 if (factor <= 0f) {
1642 throw new IllegalArgumentException(MSG_FACTOR_NEGATIVE);
1643 }
1644 return new ErodingObjectPool<>(pool, factor);
1645 }
1646
1647
1648
1649
1650
1651
1652 private static Timer getMinIdleTimer() {
1653 return TimerHolder.MIN_IDLE_TIMER;
1654 }
1655
1656
1657
1658
1659
1660
1661
1662
1663
1664
1665
1666
1667
1668
1669
1670
1671
1672
1673
1674
1675
1676
1677
1678
1679 @Deprecated
1680 public static <K, V> void prefill(final KeyedObjectPool<K, V> keyedPool,
1681 final Collection<K> keys, final int count) throws Exception,
1682 IllegalArgumentException {
1683 if (keys == null) {
1684 throw new IllegalArgumentException(MSG_NULL_KEYS);
1685 }
1686 keyedPool.addObjects(keys, count);
1687 }
1688
1689
1690
1691
1692
1693
1694
1695
1696
1697
1698
1699
1700
1701
1702
1703
1704
1705
1706
1707
1708 @Deprecated
1709 public static <K, V> void prefill(final KeyedObjectPool<K, V> keyedPool,
1710 final K key, final int count) throws Exception,
1711 IllegalArgumentException {
1712 if (keyedPool == null) {
1713 throw new IllegalArgumentException(MSG_NULL_KEYED_POOL);
1714 }
1715 keyedPool.addObjects(key, count);
1716 }
1717
1718
1719
1720
1721
1722
1723
1724
1725
1726
1727
1728
1729
1730
1731
1732
1733
1734 @Deprecated
1735 public static <T> void prefill(final ObjectPool<T> pool, final int count)
1736 throws Exception {
1737 if (pool == null) {
1738 throw new IllegalArgumentException(MSG_NULL_POOL);
1739 }
1740 pool.addObjects(count);
1741 }
1742
1743
1744
1745
1746
1747
1748
1749
1750
1751
1752
1753
1754 public static <K, V> KeyedPooledObjectFactory<K, V> synchronizedKeyedPooledFactory(
1755 final KeyedPooledObjectFactory<K, V> keyedFactory) {
1756 return new SynchronizedKeyedPooledObjectFactory<>(keyedFactory);
1757 }
1758
1759
1760
1761
1762
1763
1764
1765
1766
1767
1768
1769
1770
1771
1772
1773
1774
1775
1776
1777
1778
1779 public static <K, V> KeyedObjectPool<K, V> synchronizedPool(final KeyedObjectPool<K, V> keyedPool) {
1780
1781
1782
1783
1784
1785
1786
1787
1788
1789 return new SynchronizedKeyedObjectPool<>(keyedPool);
1790 }
1791
1792
1793
1794
1795
1796
1797
1798
1799
1800
1801
1802
1803
1804
1805
1806
1807
1808
1809
1810
1811 public static <T> ObjectPool<T> synchronizedPool(final ObjectPool<T> pool) {
1812 if (pool == null) {
1813 throw new IllegalArgumentException(MSG_NULL_POOL);
1814 }
1815
1816
1817
1818
1819
1820
1821
1822
1823
1824
1825
1826
1827 return new SynchronizedObjectPool<>(pool);
1828 }
1829
1830
1831
1832
1833
1834
1835
1836
1837
1838
1839
1840 public static <T> PooledObjectFactory<T> synchronizedPooledFactory(final PooledObjectFactory<T> factory) {
1841 return new SynchronizedPooledObjectFactory<>(factory);
1842 }
1843
1844
1845
1846
1847
1848
1849
1850 public PoolUtils() {
1851 }
1852 }