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

shz.core.accept.Acceptor Maven / Gradle / Ivy

There is a newer version: 2024.0.2
Show newest version
package shz.core.accept;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import shz.core.NullHelp;
import shz.core.lock.ActionAndWait;
import shz.core.thread.TFConfig;
import shz.core.thread.TPConfig;
import shz.core.thread.ThreadHelp;

import java.time.Duration;
import java.util.Collection;
import java.util.concurrent.*;
import java.util.concurrent.locks.Lock;
import java.util.concurrent.locks.ReentrantLock;

public abstract class Acceptor {
    protected static final Logger log = LoggerFactory.getLogger(Acceptor.class);
    private final String threadName;
    private final Lock lock = new ReentrantLock();
    private ExecutorService executor;
    private volatile boolean stop = true;
    protected final ActionAndWait actionAndWait;

    protected Acceptor(String threadName) {
        this.threadName = threadName;
        actionAndWait = new ActionAndWait(lock, sleepMillis());
        Runtime.getRuntime().addShutdownHook(ThreadHelp.getShutdownHookFactory().newThread(this::stop));
    }

    protected Acceptor() {
        this.threadName = getClass().getName();
        actionAndWait = new ActionAndWait(lock, sleepMillis());
        Runtime.getRuntime().addShutdownHook(ThreadHelp.getShutdownHookFactory().newThread(this::stop));
    }

    protected long sleepMillis() {
        return 0L;
    }

    public final void start() {
        if (!stop || !lock.tryLock()) return;
        try {
            if (!stop) return;
            stop = false;
            if (executor == null)
                executor = ThreadHelp.single(TPConfig.single(TFConfig.custom(threadName).eh(eh())).workQueue(new LinkedBlockingQueue<>(1)));
            executor.execute(this::run);
        } finally {
            lock.unlock();
        }
    }

    protected Thread.UncaughtExceptionHandler eh() {
        return null;
    }

    private void run() {
        while (!stop) actionAndWait.execute(() -> {
            try {
                return action();
            } catch (Exception e) {
                log.error(e.getMessage(), e);
                return null;
            }
        });
    }

    /**
     * @return 行动之后的wait时间
     */
    protected abstract Duration action();

    public final boolean isStop() {
        return stop;
    }

    public final void awaken() {
        actionAndWait.awaken();
    }

    public final boolean isRunning() {
        return actionAndWait.isRunning();
    }

    public final void stop(long intervalMillis, int times) {
        NullHelp.requireNon(intervalMillis <= 0L);
        if (!stop) {
            synchronized (this) {
                if (!stop) {
                    stop = true;
                    try {
                        int count = 0;
                        while (isRunning()) {
                            awaken();
                            if (times > 0 && ++count >= times) break;
                            TimeUnit.MILLISECONDS.sleep(intervalMillis);
                        }
                    } catch (InterruptedException ignored) {
                    }
                    executor.shutdownNow();
                }
            }
        }
    }

    public final void stop() {
        stop(100L, 100);
    }

    public final boolean push(T t) {
        if (t == null || !offer(t)) return false;
        awaken();
        return true;
    }

    protected abstract boolean offer(T t);

    public final boolean push(Collection dataset) {
        if (!offer(dataset)) return false;
        awaken();
        return true;
    }

    protected boolean offer(Collection dataset) {
        boolean mark = false;
        if (NullHelp.nonEmpty(dataset)) for (T t : dataset) mark |= t != null && offer(t);
        return mark;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy