Dans le développement de tous les jours du projet, nous rencontrons souvent les tâches de traitement des besoins asynchrones, tels que les services d'exploitation forestière, la surveillance des services et ainsi de suite. J'ai une certaine expérience dans le développement des premiers étudiants penseront à utiliser la piscine de fil, parce que le « pool de threads de mission dans » l'avantage que « créer un thread pour chaque tâche », en réutilisant fil existant, le fil continue à créer évité détruire généré pendant la surcharge. Dans le développement de Java, la pratique générale est basée classe ThreadPoolExecutor, corePoolSize personnalisé, MaxPoolSize, ThreadFactory et d'autres paramètres pour créer un pool de threads classe utilitaire. Cependant, le pool de threads est pas sans inconvénients, pour les développeurs, il est difficile d'estimer avec précision la taille de l'entreprise avant le projet en ligne, donc, comment définir correctement pool de threads corePoolSize, MaxPoolSize est une chose difficile à saisir , conduira à déraisonnable pas atteindre les performances attendues, et même conduire à l'échec en ligne. Cependant, l'utilisation de certains api de surveillance ThreadPoolExecutor nous proposons, nous pouvons le faire en temps réel le suivi de la piscine de fil et le réglage. Cet article utilisera les éléments suivants plusieurs API, combiné avec des fonctionnalités étendues fourni Cat, la surveillance soutenue de la piscine de fil.
1. pool de threads personnalisé
Je le code suivant est utilisé pour tester un pool de threads classe utilitaire
public class ThreadPoolManager<T> {
/**
* 根据cpu的数量动态的配置核心线程数和最大线程数
*/
//private static final int CPU_COUNT = Runtime.getRuntime().availableProcessors();
/**
* 核心线程数 = CPU核心数 + 1
*/
private static final int CORE_POOL_SIZE = 20;
/**
* 线程池最大线程数 = CPU核心数 * 2 + 1
*/
private static final int MAXIMUM_POOL_SIZE = 25;
private static final int QUEUE_SIZE = 1000;
/**
* 非核心线程闲置时超时1s
*/
private static final int KEEP_ALIVE = 3;
/**
* 线程池的对象
*/
private final ThreadPoolExecutor executor = new ThreadPoolExecutor(CORE_POOL_SIZE, MAXIMUM_POOL_SIZE,
KEEP_ALIVE, TimeUnit.SECONDS, new ArrayBlockingQueue<>(QUEUE_SIZE),
Executors.defaultThreadFactory(), new DiscardPolicyWithLog());
/**
* 要确保该类只有一个实例对象,避免产生过多对象消费资源,所以采用单例模式
*/
private ThreadPoolManager() {
}
private static ThreadPoolManager sInstance;
public static ThreadPoolManager getsInstance() {
if (sInstance == null) {
synchronized (ThreadPoolManager.class) {
if (sInstance == null) {
sInstance = new ThreadPoolManager();
}
}
}
return sInstance;
}
/**
* 开启一个无返回结果的线程
* @param r
*/
public void execute(Runnable r) {
executor.execute(r);
}
/**
* 开启一个有返回结果的线程
*
* @param r
* @return
*/
public Future<T> submit(Callable<T> r) {
// 把一个任务丢到了线程池中
return executor.submit(r);
}
/**
* 把任务移除等待队列
*
* @param r
*/
public void cancel(Runnable r) {
if (r != null) {
executor.getQueue().remove(r);
}
}
}
2. Ajouter la surveillance Cat
En supposant que votre chat a été intégré le suivi des projets, puis utilisez le chat SPI offre la possibilité d'étendre, nous pouvons surveiller tout besoin de se concentrer sur les indicateurs du système d'exécution. Nous voulons maintenant quelques indicateurs de suivi pool de threads d'exécution, pour nous aider à mieux optimiser le fil configuration de la piscine, d'améliorer les performances du système. Dans la méthode de construction au-dessus des outils pool de threads a été ajouté le code suivant, peut être atteint.
private ThreadPoolManager() {
StatusExtensionRegister.getInstance().register(new StatusExtension() {
@Override
public String getId() {
return "mqtt_msg_pool_monitor";
}
@Override
public String getDescription() {
return "mqtt消息处理线程池监控";
}
@Override
public Map<String, String> getProperties() {
Map<String,String> map = new HashMap<>();
//线程池曾经创建过的最大线程数量
map.put("largest-pool-size", String.valueOf(executor.getLargestPoolSize()));
map.put("max-pool-size", String.valueOf(executor.getMaximumPoolSize()));
map.put("core-pool-size", String.valueOf(executor.getCorePoolSize()));
map.put("current-pool-size", String.valueOf(executor.getPoolSize()));
map.put("queue-size", String.valueOf(executor.getQueue().size()));
return map;
}
});
}