chenjiahe
2023-07-17 d4fa5269e214e8bbe1f7dd79a922cefe9fc9916b
提交 | 用户 | age
d4fa52 1 package com.hx.util.thread;
C 2
3 import lombok.Setter;
4 import org.slf4j.Logger;
5 import org.slf4j.LoggerFactory;
6
7 import java.util.concurrent.LinkedBlockingDeque;
8 import java.util.concurrent.LinkedBlockingQueue;
9 import java.util.concurrent.ThreadPoolExecutor;
10 import java.util.concurrent.TimeUnit;
11
12
13 /**
14  * 创建线程池的,主要避免线程队列超,导致服务器爆了
15  */
16 public class ExecutorServiceTool {
17
18     /**log4j日志*/
19     private static final Logger logger = LoggerFactory.getLogger(ExecutorServiceTool.class.getName());
20
21     /**线程池-获取队列的*/
22     private ThreadPoolExecutor threadPool;
23     /**最大队列*/
24     private int maxQueue;
25     /**最大线程数*/
26     private int maxTread;
27     /**创建队列*/
28     private ThreadTaskLinkedBlockingDeque<Runnable> queue = new ThreadTaskLinkedBlockingDeque<>();
29
30     public ExecutorServiceTool() {
31     }
32
33     public ExecutorServiceTool(int initTread, int maxQueue) {
34         createThread(initTread,maxQueue);
35     }
36
37     public ExecutorServiceTool(int initTread, int maxTread, int maxQueue) {
38         this.maxTread = maxTread;
39         createThread(initTread,maxTread,maxQueue);
40     }
41
42
43     /**创建线程池
44      * @param initTread 初始化线程池
45      * @param maxQueue 最大队列新增队列,注意:这里只做传值,不限制真对
46      *                  线程池限制队列,因为限制了会报错,导致数据丢失
47      * @return 线程池
48      */
49     public ThreadPoolExecutor createThread(int initTread,int maxQueue){
50         this.threadPool = new ThreadPoolExecutor(initTread, initTread,
51                 60L, TimeUnit.SECONDS,
52                 new LinkedBlockingQueue<Runnable>());
53         this.maxQueue = maxQueue;
54         return this.threadPool;
55     }
56
57     /**创建线程池
58      * @param initTread 初始化线程池
59      * @param initTread 最大线程数
60      * @param maxQueue 最大队列新增队列,注意:这里只做传值,不限制真对
61      *                  线程池限制队列,因为限制了会报错,导致数据丢失
62      * @return 线程池
63      */
64     public ThreadPoolExecutor createThread(int initTread,int maxTread,int maxQueue){
65         this.threadPool = new ThreadPoolExecutor(initTread,maxTread,60L,TimeUnit.SECONDS,queue);
66         this.maxQueue = maxQueue;
67         return this.threadPool;
68     }
69
70     /**针对最大的队列,如果没有超过返回是false的,超过就返回是true的
71      * 单返回true的时候,就不要传入队列了
72      * @param sleepMillisecond 睡眠,毫秒秒,如果是空的,那么直接返回
73      * @return 如果没有超过返回是false的,超过就返回是true的
74      */
75     public boolean noRund(Integer sleepMillisecond){
76         if(threadPool.getQueue().size() > maxQueue){
77             if(sleepMillisecond != null && sleepMillisecond > 0){
78                 try{
79                     Thread.sleep(sleepMillisecond);
80                 }catch (Exception e){
81                     logger.error("线程池开启睡眠失败!");
82                 }
83             }
84             return true;
85         }else{
86             return false;
87         }
88     }
89
90     /**关闭*/
91     public void shutdown(){
92         this.threadPool.shutdown();
93     }
94
95     /**
96      * 自定义线程任务阻塞队列. 在活跃线程数小于最大支持线程数的情况下,新任务不放到队列从而激发线程池创建新线程及时处理.
97      * 解决使用LinkedBlockingDeque无限队列,线程池只有核心线程在处理。maximumPoolSize未启作用的问题。
98      *
99      * @author chenjiahe
100      */
101     @Setter
102     private class ThreadTaskLinkedBlockingDeque<E> extends LinkedBlockingDeque<E> {
103         @Override
104         public boolean offer(E e) {
105             int activeThreadNum = threadPool.getActiveCount();
106             if (activeThreadNum < maxTread) {
107                 return false;
108             }
109             return offerLast(e);
110         }
111     }
112
113     /****************************************************************************************/
114
115     public int getMaxQueue() {
116         return maxQueue;
117     }
118
119     public void setMaxQueue(int maxQueue) {
120         this.maxQueue = maxQueue;
121     }
122
123     public ThreadPoolExecutor getThreadPool() {
124         return threadPool;
125     }
126
127     public void setThreadPool(ThreadPoolExecutor threadPool) {
128         this.threadPool = threadPool;
129     }
130
131 }