概要

GenericObjectPool是一个通用对象池框架。线程安全的。

当我们频繁创建、销毁一个对象,或考虑对象服用时,它就能解决你的问题

GenericObjectPool

GenericObjectPool是一个通用的对象池框架。

创建时需要传入PooledObjectFactory,PooledObjectFactory内提供了维修对象池的API。

  1. public interface PooledObjectFactory<T> {
  2. //创建对象
  3. PooledObject<T> makeObject() throws Exception;
  4. //销毁对象
  5. void destroyObject(PooledObject<T> var1) throws Exception;
  6. //从池中取对象或归还对象到池中时,判断对象安全
  7. boolean validateObject(PooledObject<T> var1);
  8. //从池中取出对象,使用前,再次初始化对象
  9. void activateObject(PooledObject<T> var1) throws Exception;
  10. //当对象返回到空闲池时调用,钝化对象
  11. void passivateObject(PooledObject<T> var1) throws Exception;
  12. }

GenericObjectPoolConfig

基本参数

  1. GenericObjectPool 提供了后进先出(LIFO)与先进先出(FIFO)两种行为模式的池。默认为true,即当池中有空闲可用的对象时,调用borrowObject方法会返回最近(后进)的实例
  2. 当从池中获取资源或者将资源还回池中时 是否使用java.util.concurrent.locks.ReentrantLock.ReentrantLock 的公平锁机制,默认为false

控制参数

对象池配置,包含最大对象数、最大空闲对象数、最小空闲对象数等配置,示例如下:

  1. //创建对象池配置
  2. GenericObjectPoolConfig config = new GenericObjectPoolConfig();
  3. //最大连接数
  4. config.setMaxTotal(6);
  5. //最大空闲数
  6. config.setMaxIdle(3);
  7. //最小空闲数
  8. config.setMinIdle(1);
  9. //最长等待时间,3秒
  10. //当连接池资源耗尽时,等待时间,超出则抛异常,默认为-1即永不超时 。需要和blockWhenExhausted配合使用
  11. config.setMaxWaitMillis(3000);

依赖

  1. <dependency>
  2. <groupId>org.apache.commons</groupId>
  3. <artifactId>commons-pool2</artifactId>
  4. <version>2.8.0</version>
  5. </dependency>

DEMO代码

  1. public abstract class Pool<T> implements Closeable {
  2. protected GenericObjectPool<T> internalPool;
  3. public Pool() {
  4. }
  5. public Pool(final GenericObjectPoolConfig poolConfig, PooledObjectFactory<T> factory) {
  6. initPool(poolConfig, factory);
  7. }
  8. public Pool(PooledObjectFactory<T> factory) {
  9. GenericObjectPoolConfig poolConfig = new GenericObjectPoolConfig();
  10. poolConfig.setMinIdle(2);
  11. poolConfig.setMaxIdle(5);
  12. poolConfig.setMaxTotal(5);
  13. poolConfig.setMaxWaitMillis(10000);
  14. initPool(poolConfig, factory);
  15. }
  16. @Override
  17. public void close() {
  18. destroy();
  19. }
  20. public boolean isClosed() {
  21. return this.internalPool.isClosed();
  22. }
  23. public void initPool(final GenericObjectPoolConfig poolConfig, PooledObjectFactory<T> factory) {
  24. if (this.internalPool != null) {
  25. try {
  26. closeInternalPool();
  27. } catch (Exception e) {
  28. }
  29. }
  30. this.internalPool = new GenericObjectPool<T>(factory, poolConfig);
  31. }
  32. public T getResource() {
  33. try {
  34. return internalPool.borrowObject();
  35. } catch (Exception e) {
  36. e.printStackTrace();
  37. }
  38. return null;
  39. }
  40. protected void returnResourceObject(final T resource) {
  41. if (resource == null) {
  42. return;
  43. }
  44. try {
  45. internalPool.returnObject(resource);
  46. } catch (Exception e) {
  47. e.printStackTrace();
  48. }
  49. }
  50. protected void returnBrokenResource(final T resource) {
  51. if (resource != null) {
  52. returnBrokenResourceObject(resource);
  53. }
  54. }
  55. protected void returnResource(final T resource) {
  56. if (resource != null) {
  57. returnResourceObject(resource);
  58. }
  59. }
  60. public void destroy() {
  61. closeInternalPool();
  62. }
  63. protected void returnBrokenResourceObject(final T resource) {
  64. try {
  65. internalPool.invalidateObject(resource);
  66. } catch (Exception e) {
  67. e.printStackTrace();
  68. }
  69. }
  70. protected void closeInternalPool() {
  71. try {
  72. internalPool.close();
  73. } catch (Exception e) {
  74. e.printStackTrace();
  75. }
  76. }
  77. public int getNumActive() {
  78. if (poolInactive()) {
  79. return -1;
  80. }
  81. return this.internalPool.getNumActive();
  82. }
  83. public int getNumIdle() {
  84. if (poolInactive()) {
  85. return -1;
  86. }
  87. return this.internalPool.getNumIdle();
  88. }
  89. public int getNumWaiters() {
  90. if (poolInactive()) {
  91. return -1;
  92. }
  93. return this.internalPool.getNumWaiters();
  94. }
  95. public long getMeanBorrowWaitTimeMillis() {
  96. if (poolInactive()) {
  97. return -1;
  98. }
  99. return this.internalPool.getMeanBorrowWaitTimeMillis();
  100. }
  101. public long getMaxBorrowWaitTimeMillis() {
  102. if (poolInactive()) {
  103. return -1;
  104. }
  105. return this.internalPool.getMaxBorrowWaitTimeMillis();
  106. }
  107. private boolean poolInactive() {
  108. return this.internalPool == null || this.internalPool.isClosed();
  109. }
  110. public void addObjects(int count) {
  111. try {
  112. for (int i = 0; i < count; i++) {
  113. this.internalPool.addObject();
  114. }
  115. } catch (Exception e) {
  116. e.printStackTrace();
  117. }
  118. }
  119. }
  1. public class WebDriverPool extends Pool<ChromeDriver> {
  2. public WebDriverPool() {
  3. super(new WebDriverFactory());
  4. }
  5. public WebDriverPool(GenericObjectPoolConfig poolConfig, PooledObjectFactory<ChromeDriver> factory) {
  6. super(poolConfig, factory);
  7. }
  8. @Override
  9. public void returnResource(ChromeDriver resource) {
  10. super.returnResource(resource);
  11. }
  12. }
  1. public class WebDriverFactory implements PooledObjectFactory<ChromeDriver> {
  2. @Override
  3. public PooledObject<ChromeDriver> makeObject() {
  4. return new DefaultPooledObject<>(ChromeDriverUtil.getSimpleDriver());
  5. }
  6. @Override
  7. public void destroyObject(PooledObject<ChromeDriver> pooledObject) throws Exception {
  8. pooledObject.getObject().quit();
  9. }
  10. @Override
  11. public boolean validateObject(PooledObject<ChromeDriver> pooledObject) {
  12. boolean flag = false;
  13. ChromeDriver driver = pooledObject.getObject();
  14. if (driver != null) {
  15. flag = true;
  16. }
  17. return flag;
  18. }
  19. @Override
  20. public void activateObject(PooledObject<ChromeDriver> pooledObject) throws Exception {
  21. }
  22. @Override
  23. public void passivateObject(PooledObject<ChromeDriver> pooledObject) throws Exception {
  24. }
  25. }