java线程池统一管理模型

线程统一管理

按照业务,建立多个线程池,每个线程池的线程独立。这样避免了多个业务之间的影响。如果多个业务共用一个线程池,会因为一个业务阻塞导致整个服务雪崩。
默认线程池,为边缘业务提供统一线程管理。不需要每个业务都建立独立的线程池,一些边缘的小型业务可以使用系统默认的线程池。
整体线程状态查询。可以查询整个系统的线程状态,分析哪些业务产生了阻塞。

自定义线程工厂

每个线程池都需要配一个threadFactory.
有两个地方需要注意:一个是线程的名字必须有明确的区分,一个是AtomicInteger的超界处理。

public class ThreadPoolThreadFactory implements ThreadFactory {
    private AtomicInteger atomicInteger = new AtomicInteger();
    private String threadName;

    public ThreadPoolThreadFactory() {
        this(ThreadPoolThreadFactory.class.getSimpleName());
    }

    public ThreadPoolThreadFactory(String threadName) {
        this.threadName = threadName;
    }

    @Override
    public Thread newThread(Runnable r) {
        int number = atomicInteger.getAndUpdate(p -> (p + 1) % Integer.MAX_VALUE);
        return new Thread(r, threadName + number);
    }

}

自定义线程池工厂

  1. 提供默认线程池,不需要指定线程池名称。
  2. 可以自定义线程池,以及线程池的名称。
  3. 如果指定的线程池名称不存在,就会按照默认配置创建一个新的线程池。
  4. 线程池用ThreadPoolExecutor,而不是Executors的便利接口。
  5. 提供所有线程池的统计接口。

/**
 * @author yunzhong
 *
 */
public class ThreadPoolFactory {
    public static final String DEFAULT_POOL = "DEFAULT_POOL";

    private static final Map<String, ThreadPoolExecutor> poolMap = new ConcurrentHashMap<>();

    private static ThreadPoolConfig threadPoolConfig = null;

    public static ThreadPoolExecutor getPool() {
        return getPool(DEFAULT_POOL);
    }

    /**
     * @param poolName
     * @return
     */
    public static ThreadPoolExecutor getPool(String poolName) {
        if (poolMap.containsKey(poolName)) {
            return poolMap.get(poolName);
        } else {
            synchronized (poolMap) {
                if (!poolMap.containsKey(poolName)) {
                    if (threadPoolConfig == null) {
                        threadPoolConfig = SpringUtil.getBean(ThreadPoolConfig.class);
                    }
                    poolMap.put(poolName,
                            new ThreadPoolExecutor(threadPoolConfig.getCorePoolSize(),
                                    threadPoolConfig.getMaximumPoolSize(), threadPoolConfig.getKeepAliveTime(),
                                    TimeUnit.MILLISECONDS, new ArrayBlockingQueue<>(threadPoolConfig.getQueueSize()),
                                    new ThreadPoolThreadFactory(DEFAULT_POOL), new ThreadPoolExecutor.AbortPolicy()));
                }
            }
            return poolMap.get(poolName);
        }
    }

    /**
     * @param poolName
     * @param corePoolSize
     * @param maximumPoolSize
     * @param keepAliveTime
     * @param queueSize
     * @param handler
     * @return
     */
    public static ThreadPoolExecutor getPool(String poolName, int corePoolSize, int maximumPoolSize, int keepAliveTime,
            int queueSize, RejectedExecutionHandler handler) {
        if (poolMap.containsKey(poolName)) {
            return poolMap.get(poolName);
        } else {
            synchronized (poolMap) {
                if (!poolMap.containsKey(poolName)) {
                    if (threadPoolConfig == null) {
                        threadPoolConfig = SpringUtil.getBean(ThreadPoolConfig.class);
                    }
                    poolMap.put(poolName,
                            new ThreadPoolExecutor(corePoolSize, maximumPoolSize, keepAliveTime, TimeUnit.MILLISECONDS,
                                    new ArrayBlockingQueue<>(queueSize), new ThreadPoolThreadFactory(DEFAULT_POOL),
                                    handler));
                }
            }
            return poolMap.get(poolName);
        }
    }

    /**
     * @return
     */
    public static ThreadPoolsInfo getInfo() {
        ThreadPoolsInfo info = new ThreadPoolsInfo();
        Iterator<Entry<String, ThreadPoolExecutor>> iterator = poolMap.entrySet().iterator();
        while (iterator.hasNext()) {
            Entry<String, ThreadPoolExecutor> next = iterator.next();
            String key = next.getKey();
            ThreadPoolExecutor value = next.getValue();
            ThreadPoolInfo poolInfo = new ThreadPoolInfo(value);
            info.getInfos().put(key, poolInfo);
            info.appendActiveCount(poolInfo.getActiveCount());
            info.appendWaitingSize(poolInfo.getWaitingSize());
        }
        return info;
    }

    public static void shutdown(String poolName) {
        if (StringUtils.isEmpty(poolName)) {
            return;
        }
        ThreadPoolExecutor threadPoolExecutor = poolMap.get(poolName);
        if (threadPoolExecutor == null) {
            return;
        }
        synchronized (poolMap) {
            if (poolMap.containsKey(poolName)) {
                poolMap.remove(poolName);
                if (!threadPoolExecutor.isShutdown()) {
                    threadPoolExecutor.shutdownNow();
                }
                boolean isShutdown = false;
                try {
                    isShutdown = threadPoolExecutor.awaitTermination(1000L, TimeUnit.MILLISECONDS);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                if (!isShutdown) {
                    System.out.println("Invoke thread pool shutdown ,but raised exception .");
                }
            }
        }
    }
}

线程池核心概念:

    /**
     * 
     * <pre>
     * corePoolSize : 核心线程数线程数定义了最小可以同时运行的线程数量。 
     * maximumPoolSize :当队列中存放的任务达到队列容量的时候,当前可以同时运行的线程数量变为最大线程数。
     * keepAliveTime,unit: 存活时间
     * workQueue:当新任务来的时候会先判断当前运行的线程数量是否达到核心线程数,如果达到的话,新任务就会被存放在队列中。
     * handler: workQueue饱和策略.
     * </pre>
     * 
     * <pre>
     * 饱和策略(如果线程数量达到最大线程数量并且队列也已经被放满):
     * ThreadPoolExecutor.AbortPolicy:抛出 RejectedExecutionException来拒绝新任务的处理。
     * ThreadPoolExecutor.CallerRunsPolicy:调用当前线程运行任务。如果当前程序已关闭,则会丢弃该任务。
     * ThreadPoolExecutor.DiscardPolicy: 不处理新任务,直接丢弃掉。
     * ThreadPoolExecutor.DiscardOldestPolicy: 丢弃最早的未处理的任务请求。
     * </pre>
     */

线程池信息模型:

public class ThreadPoolsInfo {

    /**
     * @author yunzhong
     *
     */
    public static class ThreadPoolInfo {
        private int corePoolSize;
        private int maximumPoolSize;
        private int activeCount;
        private int remainingCapacity;
        private int waitingSize;

        public ThreadPoolInfo(ThreadPoolExecutor threadPoolExecutor) {
            corePoolSize = threadPoolExecutor.getCorePoolSize();
            maximumPoolSize = threadPoolExecutor.getMaximumPoolSize();
            activeCount = threadPoolExecutor.getActiveCount();
            remainingCapacity = threadPoolExecutor.getQueue().remainingCapacity();
            waitingSize = threadPoolExecutor.getQueue().size();
        }

        public int getCorePoolSize() {
            return corePoolSize;
        }

        public void setCorePoolSize(int corePoolSize) {
            this.corePoolSize = corePoolSize;
        }

        public int getMaximumPoolSize() {
            return maximumPoolSize;
        }

        public void setMaximumPoolSize(int maximumPoolSize) {
            this.maximumPoolSize = maximumPoolSize;
        }

        public int getActiveCount() {
            return activeCount;
        }

        public void setActiveCount(int activeCount) {
            this.activeCount = activeCount;
        }

        public int getRemainingCapacity() {
            return remainingCapacity;
        }

        public void setRemainingCapacity(int remainingCapacity) {
            this.remainingCapacity = remainingCapacity;
        }

        public int getWaitingSize() {
            return waitingSize;
        }

        public void setWaitingSize(int waitingSize) {
            this.waitingSize = waitingSize;
        }

    }

    private int totalActiveCount;
    private int totalWaitingSize;

    private Map<String, ThreadPoolInfo> infos = new HashMap<>();

    public int getTotalActiveCount() {
        return totalActiveCount;
    }

    public void setTotalActiveCount(int totalActiveCount) {
        this.totalActiveCount = totalActiveCount;
    }

    public int getTotalWaitingSize() {
        return totalWaitingSize;
    }

    public void setTotalWaitingSize(int totalWaitingSize) {
        this.totalWaitingSize = totalWaitingSize;
    }

    public Map<String, ThreadPoolInfo> getInfos() {
        return infos;
    }

    public void setInfos(Map<String, ThreadPoolInfo> infos) {
        this.infos = infos;
    }

    public void appendActiveCount(int activeCount) {
        this.totalActiveCount += activeCount;
    }

    public void appendWaitingSize(int waitingSize) {
        this.totalWaitingSize += waitingSize;
    }
}

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java中,线程池是一种用于管理和复用线程的机制,可以提高系统的性能和资源利用率。通过使用线程池,可以避免频繁创建和销毁线程的开销,提高线程的复用性和执行效率。 Java提供了ThreadPoolExecutor类作为线程池的实现类,它继承自AbstractExecutorService类,是Java并发包(java.util.concurrent)中线程池的核心实现类。 要使用线程池,首先需要创建一个ThreadPoolExecutor对象,并指定线程池的参数,例如核心线程数、最大线程数、线程空闲时间等。然后,可以将任务提交给线程池执行,线程池会自动管理线程的创建、复用和销毁。 以下是一个简单的Java线程池管理的示例代码: ```java import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadPoolExample { public static void main(String[] args) { // 创建一个固定大小的线程池,核心线程数为5 ExecutorService executor = Executors.newFixedThreadPool(5); // 提交任务给线程池执行 for (int i = 0; i < 10; i++) { final int taskId = i; executor.execute(new Runnable() { public void run() { System.out.println("Task " + taskId + " is being executed."); } }); } // 关闭线程池 executor.shutdown(); } } ``` 上述代码中,通过Executors类的静态方法newFixedThreadPool创建了一个固定大小为5的线程池。然后,通过execute方法提交了10个任务给线程池执行。每个任务都会打印出自己的任务ID。最后,调用shutdown方法关闭线程池

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值