package com.example.catchTheLetters.utils; import lombok.Getter; import lombok.Setter; import org.jetbrains.annotations.NotNull; import java.util.concurrent.ConcurrentLinkedDeque; import java.util.function.Consumer; import java.util.function.Supplier; /** * 对象池(防止频繁创建对象触发GC) * @param <T> 对象类型 * @author spyn */ public class ObjectPool<T> implements Iterable<T> { /** * 对象池 */ private final ConcurrentLinkedDeque<T> pool; /** * 重置对象委托 */ private final Consumer<T> reset; /** * 创建对象委托 */ private final Supplier<T> factory; /** * 对象池上限 */ @Setter @Getter private Integer limit; /** * 是否阻塞 */ @Getter @Setter private Boolean block; /** * 当前对象数 */ private Integer count; /** * 构造函数 * @param factory 创建对象委托 * @param reset 重置对象委托 * @param block 是否阻塞 * @param limit 对象池上限 */ public ObjectPool(Supplier<T> factory, Consumer<T> reset, Boolean block, Integer limit) { this.pool = new ConcurrentLinkedDeque<>(); this.factory = factory; this.reset = reset; this.block = block; this.limit = limit; // 预先创建对象 for (int i = 0; i < limit; i++) { this.pool.push(factory.get()); } count = limit; } /** * 构造函数 * @param factory 创建对象委托 * @param reset 重置对象委托 */ public ObjectPool(Supplier<T> factory, Consumer<T> reset) { this(factory, reset, false, 10); } /** * 取出一个对象 * @return 对象 */ public T borrowObject() throws InterruptedException { if (!pool.isEmpty()) return pool.pop(); // 如果对象池为空,且此时没到上限,创建新对象,否则查看是否阻塞,若不阻塞,则返回null,否则等待 if (count < limit) { count++; return factory.get(); } if (!block) { return null; } synchronized (this) { while (pool.isEmpty()) { this.wait(); } } return pool.pop(); } /** * 存入一个对象 * @param object 对象 */ public void returnObject(T object) { if (object == null) { return; } // 重置对象 reset.accept(object); synchronized (this) { this.pool.push(object); this.notify(); } } /** * 清空对象池 */ public void clear() { this.pool.clear(); } /** * 覆写迭代器,便于遍历对象池 * @return 迭代器 */ @NotNull @Override public java.util.Iterator<T> iterator() { return this.pool.iterator(); } }