Apache の commons-pool 久々に目に留めたのですが、
2018-6-14 に、Maven セントラルリポジトリに、UPされてた。
MariaDB で発生していたバグ、
[POOL-336] GenericObjectPool's borrowObject lock if create() fails with Error - ASF JIRA
など、対応されてた。
久々に目に留まったので、ちょっとラムダで書く、一般的に使えそうなコードを書いてみました。
import java.util.function.Consumer; import org.apache.commons.pool2.BasePooledObjectFactory; import org.apache.commons.pool2.impl.GenericObjectPool; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; /** * GenericPoolProcess */ public final class GenericPoolProcess<T>{ private static GenericPoolProcess inst; private GenericObjectPool<T> pool; private GenericObjectPoolConfig<T> config; private GenericPoolProcess(int maxIdle, int maxTotal, BasePooledObjectFactory<T> factory){ config = new GenericObjectPoolConfig<T>(); config.setMaxIdle(maxIdle); config.setMaxTotal(maxTotal); pool = new GenericObjectPool<>(factory, config); try{ for(int i=0; i < maxIdle; i++){ pool.addObject(); } }catch(Exception ex){ throw new RuntimeException(ex); } } @SuppressWarnings("unchecked") public static synchronized <T> GenericPoolProcess<T> init(int maxIdle, int maxTotal, BasePooledObjectFactory<T> factory){ if (maxIdle < 0) throw new IllegalArgumentException("maxIdle mulst be grater than 0"); if (maxTotal < 2) throw new IllegalArgumentException("maxTotal mulst be grater than 1"); if (inst==null) inst = new GenericPoolProcess<>(maxIdle, maxTotal, factory); return inst; } /* get は、シングルトンメソッドではない単に参照、initを実行しないとエラー */ @SuppressWarnings("unchecked") public static <T> GenericPoolProcess<T> get(){ if (inst==null) throw new RuntimeException("Not initt"); return inst; } public synchronized void close(){ if (inst != null) inst.pool.close(); } @SuppressWarnings("unchecked") public void exec(Consumer<T> consumer, Consumer<Exception> x){ try{ T obj = (T)inst.pool.borrowObject(); consumer.accept(obj); inst.pool.returnObject(obj); }catch(Exception ex){ x.accept(ex); } } @SuppressWarnings("unchecked") public static <T> GenericObjectPool<T> getPool(){ if (inst==null) throw new RuntimeException("No created pool"); return inst.pool; } }
使用は、、
// IdMaker という Object のプール準備 // IdMakerFactory は、BasePooledObjectFactoryを継承して用意する GenericPoolProcess<IdMaker> p = GenericPoolProcess.init(1, 3, new IdMakerFactory()); // プールから取り出し実行 p.exec(t->{ // t is IdMaker String id = t.getId(); }, x->x.printStackTrace()); p.close();
なんか、こうじゃなくて、Google guice AOP で書ける気がしてきました。
そうすれば、アノテーションメソッドで Pool Object を取得することを
約束したメソッドを自由に書かせることができるでしょう。