mirror of
https://gitee.com/chinabugotech/hutool.git
synced 2025-07-21 15:09:48 +08:00
add pool
This commit is contained in:
@@ -17,7 +17,7 @@ import org.dromara.hutool.core.exception.HutoolException;
|
||||
/**
|
||||
* Bean异常
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public class BeanException extends HutoolException {
|
||||
private static final long serialVersionUID = -8096998667745023423L;
|
||||
|
@@ -23,7 +23,7 @@ import java.util.TreeMap;
|
||||
* 算法实现:<a href="https://weblogs.java.net/blog/2007/11/27/consistent-hashing">https://weblogs.java.net/blog/2007/11/27/consistent-hashing</a>
|
||||
*
|
||||
* @param <T> 节点类型
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public class ConsistentHash<T> implements Serializable {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
@@ -21,7 +21,7 @@ import java.util.PriorityQueue;
|
||||
/**
|
||||
* 有界优先队列<br>
|
||||
* 按照给定的排序规则,排序元素,当队列满时,按照给定的排序规则淘汰末尾元素(去除末尾元素)
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*
|
||||
* @param <E> 成员类型
|
||||
*/
|
||||
|
@@ -17,7 +17,7 @@ import org.dromara.hutool.core.exception.HutoolException;
|
||||
/**
|
||||
* 比较异常
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public class ComparatorException extends HutoolException {
|
||||
private static final long serialVersionUID = 4475602435485521971L;
|
||||
|
@@ -21,7 +21,7 @@ import java.util.Set;
|
||||
* 基本变量类型的枚举<br>
|
||||
* 基本类型枚举包括原始类型和包装类型
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public enum BasicType {
|
||||
/**
|
||||
|
@@ -19,7 +19,7 @@ import org.dromara.hutool.core.text.StrUtil;
|
||||
/**
|
||||
* 转换异常
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public class ConvertException extends HutoolException {
|
||||
private static final long serialVersionUID = 4730597402855274362L;
|
||||
|
@@ -17,7 +17,7 @@ import org.dromara.hutool.core.text.StrUtil;
|
||||
|
||||
/**
|
||||
* 工具类异常
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public class DateException extends RuntimeException{
|
||||
private static final long serialVersionUID = 8247610319171014183L;
|
||||
|
@@ -40,7 +40,7 @@ import java.util.TimeZone;
|
||||
* 此类继承了{@link Date},并提供扩展方法,如时区等。<br>
|
||||
* 此类重写了父类的{@code toString()}方法,返回值为"yyyy-MM-dd HH:mm:ss"格式
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public class DateTime extends Date {
|
||||
private static final long serialVersionUID = -5395712593979185936L;
|
||||
|
@@ -39,7 +39,7 @@ import java.util.stream.Collectors;
|
||||
/**
|
||||
* 日期时间工具类
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
* @see TimeUtil java8日志工具类
|
||||
* @see DatePattern 日期常用格式工具类
|
||||
*/
|
||||
|
@@ -15,7 +15,7 @@ package org.dromara.hutool.core.exception;
|
||||
/**
|
||||
* 克隆异常
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public class CloneException extends HutoolException {
|
||||
private static final long serialVersionUID = 6774837422188798989L;
|
||||
|
@@ -15,7 +15,7 @@ package org.dromara.hutool.core.exception;
|
||||
/**
|
||||
* 依赖异常
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
* @since 4.0.10
|
||||
*/
|
||||
public class DependencyException extends HutoolException {
|
||||
|
@@ -15,7 +15,7 @@ package org.dromara.hutool.core.exception;
|
||||
/**
|
||||
* 未初始化异常
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public class NotInitedException extends HutoolException {
|
||||
private static final long serialVersionUID = 8247610319171014183L;
|
||||
|
@@ -15,7 +15,7 @@ package org.dromara.hutool.core.exception;
|
||||
/**
|
||||
* 验证异常
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public class ValidateException extends StatefulException {
|
||||
private static final long serialVersionUID = 6057602589533840889L;
|
||||
|
@@ -59,7 +59,7 @@ import java.util.Objects;
|
||||
* IO工具类<br>
|
||||
* IO工具类只是辅助流的读写,并不负责关闭流。原因是流可能被多次读写,读写关闭后容易造成问题。
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public class IoUtil extends NioUtil {
|
||||
|
||||
|
@@ -18,7 +18,7 @@ import org.dromara.hutool.core.text.StrUtil;
|
||||
/**
|
||||
* 资源文件或资源不存在异常
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
* @since 4.0.2
|
||||
*/
|
||||
public class NoResourceException extends IORuntimeException {
|
||||
|
@@ -38,7 +38,7 @@ import java.util.function.Predicate;
|
||||
/**
|
||||
* 网络相关工具
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public class NetUtil {
|
||||
|
||||
|
@@ -27,7 +27,7 @@ import java.nio.file.NoSuchFileException;
|
||||
/**
|
||||
* 上传的文件对象
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public class UploadFile {
|
||||
|
||||
|
@@ -15,7 +15,7 @@ package org.dromara.hutool.core.net.multipart;
|
||||
/**
|
||||
* 上传文件设定文件
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*
|
||||
*/
|
||||
public class UploadSetting {
|
||||
|
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2023. looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.pool;
|
||||
|
||||
/**
|
||||
* 对象工厂接口,用于自定义对象创建、验证和销毁<br>
|
||||
* 来自:https://github.com/DanielYWoo/fast-object-pool/
|
||||
*
|
||||
* @param <T> 对象类型
|
||||
* @author Daniel
|
||||
*/
|
||||
public interface ObjectFactory<T> {
|
||||
/**
|
||||
* 创建对象
|
||||
*
|
||||
* @return 创建的对象
|
||||
*/
|
||||
T create();
|
||||
|
||||
/**
|
||||
* 验证对象可用性,一般用于对象池中借出对象和返还对象前的验证操作。
|
||||
*
|
||||
* @param t 被验证的对象
|
||||
* @return 是否可用
|
||||
*/
|
||||
boolean validate(T t);
|
||||
|
||||
/**
|
||||
* 销毁对象,用于在验证对象不可用或不需要时的销毁逻辑。
|
||||
*
|
||||
* @param t 被销毁的对象
|
||||
*/
|
||||
void destroy(T t);
|
||||
}
|
@@ -0,0 +1,44 @@
|
||||
/*
|
||||
* Copyright (c) 2023. looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.pool;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.Serializable;
|
||||
|
||||
/**
|
||||
* 对象池接口,提供:
|
||||
* <ul>
|
||||
* <li>{@link #borrowObject()} 对象借出。</li>
|
||||
* <li>{@link #returnObject(Poolable)}对象归还。</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param <T> 对象类型
|
||||
* @author looly
|
||||
*/
|
||||
public interface ObjectPool<T> extends Closeable, Serializable {
|
||||
|
||||
/**
|
||||
* 借出对象
|
||||
*
|
||||
* @return 对象
|
||||
*/
|
||||
Poolable<T> borrowObject();
|
||||
|
||||
/**
|
||||
* 归还对象
|
||||
*
|
||||
* @param obj 对象
|
||||
* @return this
|
||||
*/
|
||||
ObjectPool<T> returnObject(final Poolable<T> obj);
|
||||
}
|
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2023. looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.pool;
|
||||
|
||||
/**
|
||||
* 对象池配置,提供基本的配置项,包括:
|
||||
* <ul>
|
||||
* <li>最小池大小(初始大小)</li>
|
||||
* <li>最大池大小</li>
|
||||
* <li>最大池大小</li>
|
||||
* <li>最长等待时间</li>
|
||||
* <li>最长空闲时间</li>
|
||||
* </ul>
|
||||
*/
|
||||
public class PoolConfig {
|
||||
private int minSize;
|
||||
private int maxSize;
|
||||
|
||||
private long maxWait;
|
||||
private long maxIdle;
|
||||
|
||||
public int getMinSize() {
|
||||
return minSize;
|
||||
}
|
||||
|
||||
public PoolConfig setMinSize(final int minSize) {
|
||||
this.minSize = minSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
public int getMaxSize() {
|
||||
return maxSize;
|
||||
}
|
||||
|
||||
public PoolConfig setMaxSize(final int maxSize) {
|
||||
this.maxSize = maxSize;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getMaxWait() {
|
||||
return maxWait;
|
||||
}
|
||||
|
||||
public PoolConfig setMaxWait(final long maxWait) {
|
||||
this.maxWait = maxWait;
|
||||
return this;
|
||||
}
|
||||
|
||||
public long getMaxIdle() {
|
||||
return maxIdle;
|
||||
}
|
||||
|
||||
public PoolConfig setMaxIdle(final long maxIdle) {
|
||||
this.maxIdle = maxIdle;
|
||||
return this;
|
||||
}
|
||||
}
|
@@ -0,0 +1,19 @@
|
||||
/*
|
||||
* Copyright (c) 2023. looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.pool;
|
||||
|
||||
import org.dromara.hutool.core.lang.wrapper.Wrapper;
|
||||
|
||||
public interface Poolable<T> extends Wrapper<T> {
|
||||
void returnObject();
|
||||
}
|
@@ -0,0 +1,23 @@
|
||||
/*
|
||||
* Copyright (c) 2023. looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 对象池封装实现<br>
|
||||
* 整体参考了:
|
||||
* <ul>
|
||||
* <li>https://github.com/DanielYWoo/fast-object-pool/</li>
|
||||
* <li>https://github.com/apache/commons-pool</li>
|
||||
* </ul>
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
package org.dromara.hutool.core.pool;
|
@@ -0,0 +1,98 @@
|
||||
/*
|
||||
* Copyright (c) 2023. looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.pool.partition;
|
||||
|
||||
import org.dromara.hutool.core.io.IoUtil;
|
||||
import org.dromara.hutool.core.pool.*;
|
||||
import org.dromara.hutool.core.thread.ThreadUtil;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.ArrayBlockingQueue;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
|
||||
/**
|
||||
* 分区对象池实现<br>
|
||||
* 来自:https://github.com/DanielYWoo/fast-object-pool/blob/master/src/main/java/cn/danielw/fop/ObjectPool.java
|
||||
*
|
||||
* @param <T> 对象类型
|
||||
* @author Daniel, Looly
|
||||
*/
|
||||
public class PartitionObjectPool<T> implements ObjectPool<T> {
|
||||
private static final long serialVersionUID = 1L;
|
||||
|
||||
private final PartitionPoolConfig config;
|
||||
// 分区,创建后不再变更,线程安全
|
||||
private final PoolPartition<T>[] partitions;
|
||||
|
||||
private boolean closed;
|
||||
|
||||
/**
|
||||
* 构造
|
||||
*
|
||||
* @param config 配置
|
||||
* @param factory 对象工厂,用于创建、验证和销毁对象
|
||||
*/
|
||||
@SuppressWarnings({"unchecked", "resource"})
|
||||
public PartitionObjectPool(final PartitionPoolConfig config, final ObjectFactory<T> factory) {
|
||||
this.config = config;
|
||||
|
||||
final int partitionSize = config.getPartitionSize();
|
||||
this.partitions = new PoolPartition[partitionSize];
|
||||
for (int i = 0; i < partitionSize; i++) {
|
||||
partitions[i] = new PoolPartition<>(config, createBlockingQueue(config), factory);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取持有对象总数
|
||||
*
|
||||
* @return 总数
|
||||
*/
|
||||
public int getTotal() {
|
||||
int size = 0;
|
||||
for (final PoolPartition<T> subPool : partitions) {
|
||||
size += subPool.getTotal();
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Poolable<T> borrowObject() {
|
||||
checkClosed();
|
||||
final int partitionIndex = (int) (ThreadUtil.currentThreadId() % config.getPartitionSize());
|
||||
return this.partitions[partitionIndex].borrowObject();
|
||||
}
|
||||
|
||||
public PartitionObjectPool<T> returnObject(final Poolable<T> obj) {
|
||||
checkClosed();
|
||||
final int partitionIndex = (int) (ThreadUtil.currentThreadId() % config.getPartitionSize());
|
||||
this.partitions[partitionIndex].returnObject(obj);
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
this.closed = true;
|
||||
IoUtil.closeQuietly(this.partitions);
|
||||
}
|
||||
|
||||
protected BlockingQueue<Poolable<T>> createBlockingQueue(final PoolConfig poolConfig) {
|
||||
return new ArrayBlockingQueue<>(poolConfig.getMaxSize());
|
||||
}
|
||||
|
||||
private void checkClosed() {
|
||||
if (this.closed) {
|
||||
throw new IllegalStateException("Object Pool is closed!");
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* Copyright (c) 2023. looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.pool.partition;
|
||||
|
||||
import org.dromara.hutool.core.pool.PoolConfig;
|
||||
|
||||
/**
|
||||
* 分局对象池配置
|
||||
*
|
||||
* @author looly
|
||||
*/
|
||||
public class PartitionPoolConfig extends PoolConfig {
|
||||
private int partitionSize;
|
||||
|
||||
public int getPartitionSize() {
|
||||
return partitionSize;
|
||||
}
|
||||
|
||||
public PartitionPoolConfig setPartitionSize(final int partitionSize) {
|
||||
this.partitionSize = partitionSize;
|
||||
return this;
|
||||
}
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 2023. looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.pool.partition;
|
||||
|
||||
import org.dromara.hutool.core.pool.Poolable;
|
||||
|
||||
public class PartitionPoolable<T> implements Poolable<T> {
|
||||
|
||||
private final T raw;
|
||||
private final PoolPartition<T> partition;
|
||||
|
||||
public PartitionPoolable(final T raw, PoolPartition<T> partition) {
|
||||
this.raw = raw;
|
||||
this.partition = partition;
|
||||
}
|
||||
|
||||
@Override
|
||||
public T getRaw() {
|
||||
return this.raw;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void returnObject() {
|
||||
this.partition.returnObject(this);
|
||||
}
|
||||
}
|
@@ -0,0 +1,141 @@
|
||||
/*
|
||||
* Copyright (c) 2023. looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
package org.dromara.hutool.core.pool.partition;
|
||||
|
||||
import org.dromara.hutool.core.exception.HutoolException;
|
||||
import org.dromara.hutool.core.pool.ObjectFactory;
|
||||
import org.dromara.hutool.core.pool.PoolConfig;
|
||||
import org.dromara.hutool.core.pool.Poolable;
|
||||
|
||||
import java.io.Closeable;
|
||||
import java.io.IOException;
|
||||
import java.util.concurrent.BlockingQueue;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
public class PoolPartition<T> implements Closeable {
|
||||
|
||||
private final PoolConfig config;
|
||||
private final ObjectFactory<T> objectFactory;
|
||||
|
||||
private BlockingQueue<Poolable<T>> queue;
|
||||
// 记录对象总数(包括借出对象)
|
||||
private int total;
|
||||
|
||||
public PoolPartition(PoolConfig config, BlockingQueue<Poolable<T>> queue, ObjectFactory<T> objectFactory) {
|
||||
this.config = config;
|
||||
this.queue = queue;
|
||||
this.objectFactory = objectFactory;
|
||||
|
||||
final int minSize = config.getMinSize();
|
||||
for (int i = 0; i < minSize; i++) {
|
||||
queue.add(createPoolable());
|
||||
}
|
||||
total = minSize;
|
||||
}
|
||||
|
||||
public Poolable<T> borrowObject() {
|
||||
// 非阻塞获取
|
||||
Poolable<T> poolable = this.queue.poll();
|
||||
if (null != poolable) {
|
||||
return poolable;
|
||||
}
|
||||
|
||||
// 扩容
|
||||
if (increase(1) <= 0) {
|
||||
// 池分区已满,只能等待是否有返还的对象
|
||||
poolable = waitingPoll();
|
||||
if (null == poolable) {
|
||||
// 池空间达到最大值,但是无可用对象
|
||||
throw new HutoolException("Pool exhausted!");
|
||||
}
|
||||
}
|
||||
|
||||
// 扩容成功,继续借对象
|
||||
return borrowObject();
|
||||
}
|
||||
|
||||
/**
|
||||
* 归还对象
|
||||
*
|
||||
* @param obj 归还的对象
|
||||
* @return this
|
||||
*/
|
||||
public PoolPartition<T> returnObject(final Poolable<T> obj) {
|
||||
try {
|
||||
this.queue.put(obj);
|
||||
} catch (InterruptedException e) {
|
||||
throw new HutoolException(e);
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
public synchronized int increase(int increaseSize) {
|
||||
if (increaseSize + total > config.getMaxSize()) {
|
||||
increaseSize = config.getMaxSize() - total;
|
||||
}
|
||||
|
||||
try {
|
||||
for (int i = 0; i < increaseSize; i++) {
|
||||
queue.put(createPoolable());
|
||||
}
|
||||
total += increaseSize;
|
||||
} catch (final InterruptedException e) {
|
||||
throw new HutoolException(e);
|
||||
}
|
||||
return increaseSize;
|
||||
}
|
||||
|
||||
/**
|
||||
* 销毁对象,注意此方法操作的对象必须在队列外
|
||||
*
|
||||
* @param obj 被销毁的对象
|
||||
* @return this
|
||||
*/
|
||||
public synchronized PoolPartition<T> free(final Poolable<T> obj) {
|
||||
objectFactory.destroy(obj.getRaw());
|
||||
total--;
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取对象总数,包括借出对象数
|
||||
*
|
||||
* @return 对象数
|
||||
*/
|
||||
public int getTotal() {
|
||||
return this.total;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
this.queue.forEach(this::free);
|
||||
this.queue.clear();
|
||||
this.queue = null;
|
||||
}
|
||||
|
||||
protected Poolable<T> createPoolable() {
|
||||
return new PartitionPoolable<>(objectFactory.create(), this);
|
||||
}
|
||||
|
||||
private Poolable<T> waitingPoll() {
|
||||
final long maxWait = this.config.getMaxWait();
|
||||
try {
|
||||
if (maxWait <= 0) {
|
||||
return this.queue.take();
|
||||
}
|
||||
return this.queue.poll(maxWait, TimeUnit.MILLISECONDS);
|
||||
} catch (final InterruptedException e) {
|
||||
throw new HutoolException(e);
|
||||
}
|
||||
}
|
||||
}
|
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Copyright (c) 2023. looly(loolly@aliyun.com)
|
||||
* Hutool is licensed under Mulan PSL v2.
|
||||
* You can use this software according to the terms and conditions of the Mulan PSL v2.
|
||||
* You may obtain a copy of Mulan PSL v2 at:
|
||||
* https://license.coscl.org.cn/MulanPSL2
|
||||
* THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
|
||||
* EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
|
||||
* MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
|
||||
* See the Mulan PSL v2 for more details.
|
||||
*/
|
||||
|
||||
/**
|
||||
* 基于分区的对象池实现,参考:https://github.com/DanielYWoo/fast-object-pool
|
||||
*
|
||||
* @author Daniel, Looly
|
||||
*/
|
||||
package org.dromara.hutool.core.pool.partition;
|
@@ -43,7 +43,7 @@ import java.util.function.Predicate;
|
||||
/**
|
||||
* 类工具类 <br>
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public class ClassUtil {
|
||||
|
||||
@@ -116,7 +116,7 @@ public class ClassUtil {
|
||||
* 例如:ClassUtil这个类<br>
|
||||
*
|
||||
* <pre>
|
||||
* isSimple为false: "com.xiaoleilu.hutool.util.ClassUtil"
|
||||
* isSimple为false: "org.dromara.hutool.core.reflect.ClassUtil"
|
||||
* isSimple为true: "ClassUtil"
|
||||
* </pre>
|
||||
*
|
||||
@@ -551,7 +551,7 @@ public class ClassUtil {
|
||||
/**
|
||||
* 获得给定类所在包的名称<br>
|
||||
* 例如:<br>
|
||||
* com.xiaoleilu.hutool.util.ClassUtil =》 com.xiaoleilu.hutool.util
|
||||
* org.dromara.hutool.core.reflect.ClassUtil =》 org.dromara.hutool.core.reflect
|
||||
*
|
||||
* @param clazz 类
|
||||
* @return 包名
|
||||
@@ -571,7 +571,7 @@ public class ClassUtil {
|
||||
/**
|
||||
* 获得给定类所在包的路径<br>
|
||||
* 例如:<br>
|
||||
* com.xiaoleilu.hutool.util.ClassUtil =》 com/xiaoleilu/hutool/util
|
||||
* org.dromara.hutool.core.reflect.ClassUtil =》 org/dromara/hutool/core/reflect
|
||||
*
|
||||
* @param clazz 类
|
||||
* @return 包名
|
||||
|
@@ -675,7 +675,8 @@ public class MethodUtil {
|
||||
* 非单例模式,如果是非静态方法,每次创建一个新对象
|
||||
*
|
||||
* @param <T> 对象类型
|
||||
* @param classNameWithMethodName 类名和方法名表达式,类名与方法名用{@code .}或{@code #}连接 例如:com.xiaoleilu.hutool.StrUtil.isEmpty 或 com.xiaoleilu.hutool.StrUtil#isEmpty
|
||||
* @param classNameWithMethodName 类名和方法名表达式,类名与方法名用{@code .}或{@code #}连接
|
||||
* 例如:org.dromara.hutool.core.text.StrUtil.isEmpty 或 org.dromara.hutool.core.text.StrUtil#isEmpty
|
||||
* @param args 参数,必须严格对应指定方法的参数类型和数量
|
||||
* @return 返回结果
|
||||
*/
|
||||
@@ -689,7 +690,8 @@ public class MethodUtil {
|
||||
* 执行非static方法时,必须满足对象有默认构造方法<br>
|
||||
*
|
||||
* @param <T> 对象类型
|
||||
* @param classNameWithMethodName 类名和方法名表达式,例如:com.xiaoleilu.hutool.StrUtil#isEmpty或com.xiaoleilu.hutool.StrUtil.isEmpty
|
||||
* @param classNameWithMethodName 类名和方法名表达式,
|
||||
* 例如:org.dromara.hutool.core.text.StrUtil#isEmpty或org.dromara.hutool.core.text.StrUtil.isEmpty
|
||||
* @param isSingleton 是否为单例对象,如果此参数为false,每次执行方法时创建一个新对象
|
||||
* @param args 参数,必须严格对应指定方法的参数类型和数量
|
||||
* @return 返回结果
|
||||
|
@@ -36,7 +36,7 @@ import java.util.regex.Pattern;
|
||||
* 正则相关工具类<br>
|
||||
* 常用正则请见 {@link Validator}
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public class ReUtil {
|
||||
|
||||
|
@@ -27,7 +27,7 @@ import java.util.Map;
|
||||
* 字符串工具类<br>
|
||||
* 此工具主要针对单个字符串的操作
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public class StrUtil extends CharSequenceUtil implements StrPool {
|
||||
|
||||
|
@@ -21,7 +21,7 @@ import java.util.function.Predicate;
|
||||
* escape采用ISO Latin字符集对指定的字符串进行编码。<br>
|
||||
* 所有的空格符、标点符号、特殊字符以及其他非ASCII字符都将被转化成%xx格式的字符编码(xx等于该字符在字符集表里面的编码的16进制数字)。
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public class EscapeUtil {
|
||||
|
||||
|
@@ -233,7 +233,7 @@ public class SyncFinisher implements Closeable {
|
||||
/**
|
||||
* 工作者,为一个线程
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public abstract class Worker implements Runnable {
|
||||
|
||||
|
@@ -680,6 +680,16 @@ public class ThreadUtil {
|
||||
return (null != s) ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取当前线程ID,即TID
|
||||
*
|
||||
* @return TID
|
||||
* @since 6.0.0
|
||||
*/
|
||||
public static long currentThreadId() {
|
||||
return Thread.currentThread().getId();
|
||||
}
|
||||
|
||||
/**
|
||||
* 创建线程工厂
|
||||
*
|
||||
|
@@ -35,7 +35,7 @@ import java.util.concurrent.ThreadLocalRandom;
|
||||
/**
|
||||
* 随机工具类
|
||||
*
|
||||
* @author xiaoleilu
|
||||
* @author Looly
|
||||
*/
|
||||
public class RandomUtil {
|
||||
|
||||
|
Reference in New Issue
Block a user