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

shz.ThreadHelp Maven / Gradle / Ivy

package shz;

import java.util.Arrays;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.*;
import java.util.concurrent.ThreadPoolExecutor.AbortPolicy;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Predicate;

@SuppressWarnings("unchecked")
public final class ThreadHelp {
    private ThreadHelp() {
        throw new IllegalStateException();
    }

    public static Thread[] getAllThreads() {
        ThreadGroup root = Thread.currentThread().getThreadGroup();
        while (root.getParent() != null) root = root.getParent();
        Thread[] threads = new Thread[root.activeCount()];
        int enumerate = root.enumerate(threads);
        if (enumerate < threads.length) return Arrays.copyOf(threads, enumerate);
        return threads;
    }

    public static Thread getThread(Predicate predicate) {
        return Arrays.stream(getAllThreads()).parallel().filter(predicate).findAny().orElse(null);
    }

    public static Thread getThreadById(long id) {
        if (id <= 0L) return null;
        return getThread(t -> t.getId() == id);
    }

    public static Thread getThreadByName(String name) {
        if (Validator.isBlank(name)) return null;
        return getThread(t -> t.getName().equals(name));
    }

    public enum TPType {
        FIXED_THREAD_POOL, SINGLE_THREAD_EXECUTOR, CACHED_THREAD_POOL, SINGLE_THREAD_SCHEDULED_EXECUTOR, SCHEDULED_THREAD_POOL
    }

    public enum TFType {
        PRIVILEGED, CUSTOM
    }

    public static final class TPConfig {
        TPType tpType = TPType.FIXED_THREAD_POOL;
        int corePoolSize = -1;
        int maximumPoolSize;
        long keepAliveTime = -1L;
        TimeUnit unit;
        BlockingQueue workQueue;
        TFType tfType = TFType.CUSTOM;
        RejectedExecutionHandler handler;
        final String threadName;
        boolean daemon;
        int priority = Thread.NORM_PRIORITY;

        private TPConfig(String threadName) {
            this.threadName = threadName;
        }

        public static TPConfig of(String threadName) {
            if (Validator.isBlank(threadName)) throw new IllegalArgumentException();
            return new TPConfig(threadName);
        }

        public TPConfig tpType(TPType tpType) {
            this.tpType = tpType;
            return this;
        }

        public TPConfig corePoolSize(int corePoolSize) {
            this.corePoolSize = corePoolSize;
            return this;
        }

        public TPConfig maximumPoolSize(int maximumPoolSize) {
            this.maximumPoolSize = maximumPoolSize;
            return this;
        }

        public TPConfig keepAliveTime(long keepAliveTime) {
            this.keepAliveTime = keepAliveTime;
            return this;
        }

        public TPConfig unit(TimeUnit unit) {
            this.unit = unit;
            return this;
        }

        public TPConfig workQueue(BlockingQueue workQueue) {
            this.workQueue = workQueue;
            return this;
        }

        public TPConfig tfType(TFType tfType) {
            this.tfType = tfType;
            return this;
        }

        public TPConfig handler(RejectedExecutionHandler handler) {
            this.handler = handler;
            return this;
        }

        public TPConfig daemon(boolean daemon) {
            this.daemon = daemon;
            return this;
        }

        public TPConfig priority(int priority) {
            this.priority = priority;
            return this;
        }
    }

    public static ThreadFactory getThreadFactory(TPConfig tpConfig) {
        Objects.requireNonNull(tpConfig);
        switch (tpConfig.tfType) {
            case CUSTOM:
                return new ThreadFactory() {
                    final AtomicInteger sn = new AtomicInteger();

                    public Thread newThread(Runnable r) {
                        SecurityManager s = System.getSecurityManager();
                        ThreadGroup group = s != null ? s.getThreadGroup() : Thread.currentThread().getThreadGroup();
                        Thread t = new Thread(group, r);
                        t.setName(tpConfig.threadName + " - " + sn.incrementAndGet());
                        t.setDaemon(tpConfig.daemon);
                        t.setPriority(tpConfig.priority);
                        return t;
                    }
                };
            case PRIVILEGED:
                return Executors.privilegedThreadFactory();
            default:
                return Executors.defaultThreadFactory();
        }
    }

    /**
     * 通过配置获取线程池,并通过反射设置一些无法配置的属性
     */
    public static  T getExecutor(TPConfig tpConfig) {
        Objects.requireNonNull(tpConfig);
        T executor = null;
        switch (tpConfig.tpType) {
            case FIXED_THREAD_POOL:
                tpConfig.corePoolSize = tpConfig.corePoolSize < 0 ? Runtime.getRuntime().availableProcessors() << 1 : tpConfig.corePoolSize;
                tpConfig.maximumPoolSize = tpConfig.maximumPoolSize <= 0 || tpConfig.maximumPoolSize < tpConfig.corePoolSize
                        ? tpConfig.corePoolSize : tpConfig.maximumPoolSize;
                tpConfig.keepAliveTime = Math.max(tpConfig.keepAliveTime, 0L);
                tpConfig.unit = tpConfig.unit == null ? TimeUnit.MILLISECONDS : tpConfig.unit;
                tpConfig.workQueue = tpConfig.workQueue == null ? new LinkedBlockingQueue<>(tpConfig.maximumPoolSize << 10) : tpConfig.workQueue;
                tpConfig.handler = tpConfig.handler == null ? new AbortPolicy() : tpConfig.handler;
                executor = (T) new ThreadPoolExecutor(tpConfig.corePoolSize, tpConfig.maximumPoolSize, tpConfig.keepAliveTime,
                        tpConfig.unit, tpConfig.workQueue, getThreadFactory(tpConfig), tpConfig.handler);
                break;
            case CACHED_THREAD_POOL:
                tpConfig.corePoolSize = Math.max(tpConfig.corePoolSize, 0);
                tpConfig.maximumPoolSize = tpConfig.maximumPoolSize <= 0
                        ? Runtime.getRuntime().availableProcessors() << 1 : Math.max(tpConfig.maximumPoolSize, tpConfig.corePoolSize);
                tpConfig.keepAliveTime = tpConfig.keepAliveTime < 0L ? 60L : tpConfig.keepAliveTime;
                tpConfig.unit = tpConfig.unit == null ? TimeUnit.SECONDS : tpConfig.unit;
                tpConfig.workQueue = tpConfig.workQueue == null ? new SynchronousQueue<>() : tpConfig.workQueue;
                tpConfig.handler = tpConfig.handler == null ? new AbortPolicy() : tpConfig.handler;
                executor = (T) new ThreadPoolExecutor(tpConfig.corePoolSize, tpConfig.maximumPoolSize, tpConfig.keepAliveTime,
                        tpConfig.unit, tpConfig.workQueue, getThreadFactory(tpConfig), tpConfig.handler);
                break;
            case SINGLE_THREAD_EXECUTOR:
                tpConfig.workQueue = tpConfig.workQueue == null ? new LinkedBlockingQueue<>(1 << 10) : tpConfig.workQueue;
                executor = (T) Executors.newSingleThreadExecutor(getThreadFactory(tpConfig));
                //通过反射替换配置
                //工作队列,拒绝策略
                Map ste = ToMap.get(2).put("workQueue", tpConfig.workQueue).build();
                if (tpConfig.handler != null) ste.put("handler", tpConfig.handler);
                ToObject.fromMap((ExecutorService) AccessibleHelp.getField(executor, f -> "e".equals(f.getName())), ste);
                break;
            case SINGLE_THREAD_SCHEDULED_EXECUTOR:
                tpConfig.maximumPoolSize = tpConfig.maximumPoolSize <= 0 ? Runtime.getRuntime().availableProcessors() << 1 : tpConfig.maximumPoolSize;
                executor = (T) Executors.newSingleThreadScheduledExecutor(getThreadFactory(tpConfig));
                //通过反射替换
                //线程池中允许的最大线程数,拒绝策略
                Map stse = ToMap.get(2).put("maximumPoolSize", tpConfig.maximumPoolSize).build();
                if (tpConfig.handler != null) stse.put("handler", tpConfig.handler);
                ToObject.fromMap((ScheduledExecutorService) AccessibleHelp.getField(executor, f -> "e".equals(f.getName())), stse);
                break;
            case SCHEDULED_THREAD_POOL:
                tpConfig.corePoolSize = tpConfig.corePoolSize < 0 ? Runtime.getRuntime().availableProcessors() << 1 : tpConfig.corePoolSize;
                tpConfig.maximumPoolSize = tpConfig.maximumPoolSize <= 0 || tpConfig.maximumPoolSize < tpConfig.corePoolSize
                        ? tpConfig.corePoolSize : tpConfig.maximumPoolSize;
                tpConfig.keepAliveTime = Math.max(tpConfig.keepAliveTime, 0L);
                tpConfig.unit = tpConfig.unit == null ? TimeUnit.NANOSECONDS : tpConfig.unit;
                executor = (T) Executors.newScheduledThreadPool(tpConfig.corePoolSize, getThreadFactory(tpConfig));
                //通过反射替换
                //线程池中允许的最大线程数,空闲状态超时时间及单位,拒绝策略
                Map stp = ToMap.get(4).put("maximumPoolSize", tpConfig.maximumPoolSize)
                        .put("keepAliveTime", tpConfig.keepAliveTime).put("unit", tpConfig.unit).build();
                if (tpConfig.handler != null) stp.put("handler", tpConfig.handler);
                ToObject.fromMap(executor, stp);
                break;
            default:
                break;
        }
        return executor;
    }
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy