内容索引(Table of Contents)
Lite-pool : 轻量快速的对象池
jdk 1.8+
maven-3.3.1+(支持 toolchains)
<dependency>
<groupId>cn.nextop</groupId>
<artifactId>lite-pool</artifactId>
<version>1.0.0-RC3</version>
</dependency>
$mvn clean install -Dmaven.test.skip=true --global-toolchains ./toolchains.xml
配置项 | 默认值 | 详解 |
---|---|---|
minimum | 0 | pool中所维持的最小对象数量 |
maximum | 16 | pool中所维持的最大对象数量 |
tti | 15 分钟 | pool中对象的最大空闲时间, 可选项(0表示不过期), 单位: ms |
ttl | 60 分钟 | pool中对象的最大生存时间, 可选项(0表示不过期), 单位: ms |
tenancy | 1 分钟 | 对象泄露检测的超时时间, 可选项(0表示不过期), 单位: ms, (必须 >= interval ) |
timeout | 8 秒 | 默认的请求超时时间, 单位: ms |
interval | 15 秒 | 默认的定时检测任务时间间隔, 单位: ms |
local | true | 是否应用 ThreadAllocator 作为 L1 缓存 |
verbose | false | 是否打印日志 |
fifo | false | 对象池分配策略, 设置为false 有更好的性能 |
allocator | DefaultAllocator | 对象池分配器, 继承 AbstractAllocator 可以定制自己的对象池分配器 |
supplier | 创建pool对象的回调方法, 必选项 | |
consumer | 销毁pool对象的回调方法, 可选项 | |
validator | 验证pool对象的回调方法, 可选项 | |
validation | PULSE | 验证pool对象的的前置条件, 例如:new PoolValidation((byte)(PULSE|ACQUIRE|RELEASE)) |
public class YourPoolObject {
}
Pool<YourPoolObject> pool = new PoolBuilder<YourPoolObject>()
.local(true) // 使用ThreadAllocator作为L1缓存
.supplier(() -> new YourPoolObject())
.interval(interval)
.minimum(minimum)
.maximum(maximum)
.timeout(timeout)
.ttl(ttl)
.tti(tti)
.verbose(true)
...
.build("object pool");
pool.start();
try {
for(int i = 0; i < 1000; i++) {
YourPoolObject object = null;
try {
object = pool.acquire();
if (object != null) {
// 你的业务代码
}
} finally {
if (object != null) pool.release(object);
}
}
} finally {
pool.stop();
}
public class YourPoolObject {
}
package your.package;
public class Factory implements Supplier<YourPoolObject> {
@Override
public YourPoolObject get() {
return new YourPoolObject();
}
}
Spring配置:
<bean id="your.object.pool" class="cn.nextop.lite.pool.impl.ObjectPool"
init-method="start" destroy-method="stop">
<constructor-arg index="0" value="your.object.pool"/>
<property name="config">
<bean class="cn.nextop.lite.pool.PoolConfig">
<property name="minimum" value="10"/>
...
<property name="supplier">
<bean class="your.package.Factory"/>
</property>
</bean>
</property>
</bean>
Pool<YourPoolObject> pool = new PoolBuilder<YourPoolObject>()
.local(true) // using thread local
.supplier(() -> new YourPoolObject())
...
.build("object pool");
pool.addListener(event -> {
YourPoolObject item = event.getItem();
switch (event.getType()) {
case ACQUIRE:
// 你的业务代码
break;
case RELEASE:
// 你的业务代码
break;
case LEAKAGE:
// 你的业务代码
break;
default:
throw new AssertionError();
}
});
pool.start();
public class YourPoolAllocator<T> extends AbstractAllocator<T> {
public YourPoolAllocator(Pool<T> pool, String name) {
super(pool, name);
}
@Override
protected Slot<T> doRelease(T t) {
// 如果应用ThrealAllocator作为L1缓存, ThrealAllocator将会尝试在TheadLocal内获得pool中的对象, 如果没
// 获取到合法的对象,会尝试调用父分配器的acquire方法获得对象, 但是在release的过程中, 会一直调用
// 父分配器的release方法释放对象, 这样要求你自己实现的分配器在release的时候能够去除重复的对象.
//
// 如果pool中对象不合法, 你的分配器应该删除这个对象并调用 super.consume(t).
//
// 详细实现请参照DefaultAllocator 和 AllocationQueue.
return null;
}
@Override
protected Slot<T> doAcquire(long timeout, TimeUnit unit) {
// 在超时或者线程被中断的情况下返回 null.
// 如果请求的对象不合法, 并且此时没有超时, 采用如下步骤实现分配器:
// 步骤1 : 永久删除这个对象并调用 super.consume(t).
// 步骤2 : 再次从pool中请求对象直到超时.
//
// 详细实现请参照DefaultAllocator 和 AllocationQueue.
return null;
}
public static class Factory<T> implements PoolAllocatorFactory<T> {
@Override public final PoolAllocator<T> create(final Pool<T> v) {
String n = v.getName() + ".allocator.your.name"; return new YourPoolAllocator<>(v, n);
}
}
}
将 YourPoolAllocator
注册到 Pool
Pool<YourPoolObject> pool = new PoolBuilder<YourPoolObject>()
.allocator(new YourPoolAllocator.Factory<>())
...
.build("object pool");
MXBean : cn.nextop.lite.pool:type=PoolConfig
属性 | 可变更 | 详解 |
---|---|---|
Maximum | 是 | 参照 2.1. PoolBuilder |
Minimum | 是 | 参照 2.1. PoolBuilder |
Tenancy | 是 | 参照 2.1. PoolBuilder |
Timeout | 是 | 参照 2.1. PoolBuilder |
Tti | 是 | 参照 2.1. PoolBuilder |
Ttl | 是 | 参照 2.1. PoolBuilder |
Verbose | 是 | 参照 2.1. PoolBuilder |
MXBean : cn.nextop.lite.pool:type=PoolAllocator
属性 | 可变更 | 详解 |
---|---|---|
EntireCount | 否 | pool中全部的对象数量. |
WorkingCount | 否 | pool中处于工作状态的对象数量, 等价于 EntireCount - RestingCount . |
RestingCount | 否 | pool中处于空闲状态的对象数量. |
PendingCount | 否 | pool中处于等待的请求数量. |
测试环境 :
OS : Windows 7 Home(64bit)
CPU: Intel(R) Core(TM) i3-4710 CPU @ 3.70GHz 3.70GHz
RAM: 8.00 GB
JDK: java version "1.8.0_151"
测试用例 :
基本参数: 10 minimum, 10 maximum
TestObject object = pool.acquire();
if (object != null) pool.release(object);
(单位: ops/ms)
测试参数: 参照 BaseTest.java
测试类: 参照 LitePoolBenchmark.java 和 CommonsPool2Benchmark.java
用ThreadAllocator
做L1缓存的结果:
未用ThreadAllocator
做L1缓存的结果: