object poolを自力で実装する機会は余りないが、Apache Commons Poolが便利な局面があったのでその使い方をメモしておく。
plugins { id 'java' id 'org.springframework.boot' version '3.0.0' id 'io.spring.dependency-management' version '1.1.0' } group = 'com.example' version = '0.0.1-SNAPSHOT' sourceCompatibility = '17' configurations { compileOnly { extendsFrom annotationProcessor } } repositories { mavenCentral() } dependencies { implementation 'org.springframework.boot:spring-boot-starter-web' compileOnly 'org.projectlombok:lombok' developmentOnly 'org.springframework.boot:spring-boot-devtools' annotationProcessor 'org.projectlombok:lombok' testImplementation 'org.springframework.boot:spring-boot-starter-test' implementation 'org.apache.commons:commons-pool2' implementation 'org.apache.commons:commons-lang3' } tasks.named('test') { useJUnitPlatform() }
spring-bootと直接の関係は無いけど現実的には一緒に使うだろうし、versionも省略出来るので、こうしている。commons-lang3も無関係だけど、説明用のランダム文字列生成のために使う。
import java.util.NoSuchElementException; import org.apache.commons.lang3.RandomStringUtils; import org.apache.commons.pool2.BasePooledObjectFactory; import org.apache.commons.pool2.ObjectPool; import org.apache.commons.pool2.PooledObject; import org.apache.commons.pool2.PooledObjectFactory; import org.apache.commons.pool2.impl.DefaultPooledObject; import org.apache.commons.pool2.impl.GenericObjectPool; import org.apache.commons.pool2.impl.GenericObjectPoolConfig; public class CommonsPool2Sample { public static void main(String[] args) throws NoSuchElementException, IllegalStateException, Exception { PooledObjectFactory<String> factory = new BasePooledObjectFactory<String>() { @Override public String create() throws Exception { String created = RandomStringUtils.randomAlphanumeric(5); System.out.println("created:" + created); return created; } @Override public PooledObject<String> wrap(String obj) { return new DefaultPooledObject<>(obj); } }; GenericObjectPoolConfig<String> config = new GenericObjectPoolConfig<>(); config.setMaxTotal(3); try (ObjectPool<String> pool = new GenericObjectPool<>(factory, config)) { pool.addObjects(config.getMaxTotal()); String a1 = pool.borrowObject(); String a2 = pool.borrowObject(); String a3 = pool.borrowObject(); System.out.println(a1 + " " + a2 + " " + a3); pool.returnObject(a1); System.out.println(pool.borrowObject()); pool.borrowObject(); } } }
実用性ゼロなObjectPool
の動作確認するためだけのコードである。実行すると以下の出力をして無限待機する。
created:HpT2W created:Yz1T5 created:oVjKr oVjKr Yz1T5 HpT2W oVjKr
プールの最大数3で4個目を取得しようとするので無限ブロックする。同時実行の要件次第で setMaxWait
とかを設定する。
addObjects
はあらかじめプールにオブジェクト生成を命じるもの。これも要件次第で事前初期化か遅延かを選ぶ感じ。
create
はjavadocにThis method must support concurrent, multi-threadedactivation.
にある通り、マルチスレッド環境下では同期化の考慮が必要。