shz.core.structure.ObjectPool Maven / Gradle / Ivy
package shz.core.structure;
import shz.core.node.ConcurrentLDNode;
import java.io.*;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Supplier;
public final class ObjectPool implements Serializable {
private static final long serialVersionUID = 570295417157818604L;
private final Supplier extends E> supplier;
private final Consumer super E> closeFun;
private final int capacity, maxIdle;
private transient AtomicInteger size;
private transient AtomicInteger idle;
private transient ConcurrentLDNode head, tail;
public ObjectPool(Supplier extends E> supplier, Consumer super E> closeFun, int capacity, int maxIdle) {
this.supplier = supplier;
this.closeFun = closeFun;
this.capacity = capacity;
this.maxIdle = maxIdle;
init();
}
private void init() {
size = new AtomicInteger(maxIdle);
idle = new AtomicInteger(maxIdle);
head = tail = ConcurrentLDNode.of(null);
head.next(tail);
tail.prev(head);
for (int i = 0; i < maxIdle; ++i) head.addNext(ConcurrentLDNode.of(this.supplier.get()));
}
public ObjectPool(Supplier extends E> supplier, int maxIdle) {
this(supplier, e -> e = null, Integer.MAX_VALUE, maxIdle);
}
public ObjectPool(Supplier extends E> supplier) {
this(supplier, 64);
}
public T apply(Function super E, ? extends T> func) {
E e = get();
T t;
try {
t = func.apply(e);
} finally {
release(e);
}
return t;
}
public E get() {
ConcurrentLDNode node;
if ((node = head.next()) == tail) return get0(create());
while (!poll(node)) {
sleep();
if ((node = head.next()) == tail) return get0(create());
}
idle.decrementAndGet();
if (node.val == null) {
size.decrementAndGet();
if (node.val != null) closeFun.accept(node.val);
return get0(create());
}
return node.val;
}
private E get0(ConcurrentLDNode node) {
return node == null ? null : node.val;
}
private ConcurrentLDNode create() {
if (size.get() >= capacity) return null;
synchronized (this) {
if (size.get() >= capacity) return null;
size.incrementAndGet();
return ConcurrentLDNode.of(supplier.get());
}
}
public void release(E e) {
if (idle.get() < maxIdle) {
//高并发时idle可能超过maxIdle
idle.incrementAndGet();
head.addNext(ConcurrentLDNode.of(e));
} else size.decrementAndGet();
}
boolean poll(ConcurrentLDNode node) {
ConcurrentLDNode prev = node.prev();
ConcurrentLDNode next = node.next();
if (!prev.casNext(node, next)) return false;
else next.prev(prev);
return true;
}
void sleep() {
try {
TimeUnit.MICROSECONDS.sleep(500L);
} catch (InterruptedException ignored) {
}
}
public void accept(Consumer consumer) {
apply(t -> {
consumer.accept(t);
return null;
});
}
public int size() {
return size.get();
}
public int idle() {
return idle.get();
}
public void clear() {
for (ConcurrentLDNode next = head.next(); next != tail; next = next.next())
if (next.val != null) closeFun.accept(next.val);
head.next(tail);
tail.prev(head);
}
private void writeObject(ObjectOutputStream oos) throws IOException {
oos.defaultWriteObject();
}
private void readObject(ObjectInputStream ois) throws IOException, ClassNotFoundException {
ois.defaultReadObject();
init();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy