/* * (C) Copyright 2015-2016 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. * * Contributors: * ohun@live.cn (夜色) */ package com.mpush.tools.thread.pool; import com.mpush.api.spi.common.ExecutorFactory; import com.mpush.tools.thread.NamedThreadFactory; import io.netty.channel.EventLoopGroup; import io.netty.channel.SingleThreadEventLoop; import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.ThreadProperties; import java.util.HashMap; import java.util.Map; import java.util.Objects; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.Executor; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ThreadPoolExecutor; public final class ThreadPoolManager { public static final ThreadPoolManager I = new ThreadPoolManager(); private final ExecutorFactory executorFactory = ExecutorFactory.create(); private final NamedThreadFactory threadFactory = new NamedThreadFactory(); private final Map<String, Executor> pools = new ConcurrentHashMap<>(); public final Thread newThread(String name, Runnable target) { return threadFactory.newThread(name, target); } public Executor getRedisExecutor() { return pools.computeIfAbsent("mq", s -> executorFactory.get(ExecutorFactory.MQ)); } public Executor getEventBusExecutor() { return pools.computeIfAbsent("event-bus", s -> executorFactory.get(ExecutorFactory.EVENT_BUS)); } public ScheduledExecutorService getPushClientTimer() { return (ScheduledExecutorService) pools.computeIfAbsent("push-client-timer" , s -> executorFactory.get(ExecutorFactory.PUSH_CLIENT)); } public ScheduledExecutorService getPushTaskTimer() { return (ScheduledExecutorService) pools.computeIfAbsent("push-task-timer" , s -> executorFactory.get(ExecutorFactory.PUSH_TASK)); } public ScheduledExecutorService getAckTimer() { return (ScheduledExecutorService) pools.computeIfAbsent("ack-timer" , s -> executorFactory.get(ExecutorFactory.ACK_TIMER)); } public void register(String name, Executor executor) { Objects.requireNonNull(name); Objects.requireNonNull(executor); pools.put(name, executor); } public Map<String, Executor> getActivePools() { return pools; } public static Map<String, Object> getPoolInfo(ThreadPoolExecutor executor) { Map<String, Object> info = new HashMap<>(5); info.put("corePoolSize", executor.getCorePoolSize()); info.put("maxPoolSize", executor.getMaximumPoolSize()); info.put("activeCount(workingThread)", executor.getActiveCount()); info.put("poolSize(workThread)", executor.getPoolSize()); info.put("queueSize(blockedTask)", executor.getQueue().size()); return info; } public static Map<String, Object> getPoolInfo(EventLoopGroup executors) { Map<String, Object> info = new HashMap<>(3); int poolSize = 0, queueSize = 0, activeCount = 0; for (EventExecutor e : executors) { poolSize++; if (e instanceof SingleThreadEventLoop) { SingleThreadEventLoop executor = (SingleThreadEventLoop) e; queueSize += executor.pendingTasks(); ThreadProperties tp = executor.threadProperties(); if (tp.state() == Thread.State.RUNNABLE) { activeCount++; } } } info.put("poolSize(workThread)", poolSize); info.put("activeCount(workingThread)", activeCount); info.put("queueSize(blockedTask)", queueSize); return info; } }