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 对象类型 * @author spyn */ public class ObjectPool implements Iterable { /** * 对象池 */ private final ConcurrentLinkedDeque pool; /** * 重置对象委托 */ private final Consumer reset; /** * 创建对象委托 */ private final Supplier factory; /** * 对象池上限 */ @Setter @Getter private Integer limit; /** * 是否需要上限 */ @Getter @Setter private Boolean needLimit; /** * 当前对象数 */ private Integer count; /** * 构造函数 * * @param factory 创建对象委托 * @param reset 重置对象委托 * @param needLimit 是否需要上限 * @param limit 对象池上限 */ public ObjectPool(Supplier factory, Consumer reset, Boolean needLimit, Integer limit) { this.pool = new ConcurrentLinkedDeque<>(); this.factory = factory; this.reset = reset; this.needLimit = needLimit; this.limit = limit; // 预先创建对象 for (int i = 0; i < limit; i++) { this.pool.push(factory.get()); } count = limit; } /** * 构造函数 * * @param factory 创建对象委托 * @param reset 重置对象委托 */ public ObjectPool(Supplier factory, Consumer reset) { this(factory, reset, false, 10); } /** * 取出一个对象 * * @return 对象 */ public T borrowObject() throws InterruptedException { if (!pool.isEmpty()) return pool.pop(); // 如果对象池为空,且此时没到上限,创建新对象,否则如果需要上限约束的情况下返回null if (needLimit && count >= limit) return null; count++; return factory.get(); } /** * 存入一个对象 * * @param object 对象 */ public void returnObject(T object) { if (object == null) { return; } // 重置对象 reset.accept(object); this.pool.push(object); } /** * 清空对象池 */ public void clear() { this.pool.clear(); } /** * 覆写迭代器,便于遍历对象池 * * @return 迭代器 */ @NotNull @Override public java.util.Iterator iterator() { return this.pool.iterator(); } }