All Downloads are FREE. Search and download functionalities are using the official Maven repository.

shz.core.structure.ObjectPool Maven / Gradle / Ivy

There is a newer version: 2024.0.2
Show newest version
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 supplier;
    private final Consumer closeFun;
    private final int capacity, maxIdle;
    private transient AtomicInteger size;
    private transient AtomicInteger idle;
    private transient ConcurrentLDNode head, tail;

    public ObjectPool(Supplier supplier, Consumer 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 supplier, int maxIdle) {
        this(supplier, e -> e = null, Integer.MAX_VALUE, maxIdle);
    }

    public ObjectPool(Supplier supplier) {
        this(supplier, 64);
    }

    public  T apply(Function 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