hjg
2023-10-14 f6c2f15c37aef4675dda01fb5ec17cde4e141c3f
提交 | 用户 | 时间
c5bdf3 1 package com.mandi.fendan.util;
A 2
3 import javax.validation.constraints.NotNull;
4 import java.util.concurrent.LinkedBlockingQueue;
5 import java.util.concurrent.ThreadFactory;
6 import java.util.concurrent.ThreadPoolExecutor;
7 import java.util.concurrent.TimeUnit;
8 import java.util.concurrent.atomic.AtomicInteger;
9
10 /**
11  * 线程池的工具类
12  * 用于进行线程的管理,防止重复创建、杀死线程。
13  *
14
15  * 多线程运行期间,如果系统不断的创建、杀死新线程,
16  * 会产生过度消耗系统资源,以及过度切换线程的问题,甚至可能导致系统资源的崩溃。
17  * 因此需要线程池,对线程进行管理。
18  */
19 public class ThreadPoolUtil {
20
21     private String TAG = getClass().getName();
22     private static volatile ThreadPoolUtil mInstance;
23     //核心线程池的数量,同时能够执行的线程数量
24     private int corePoolSize;
25     //最大线程池数量,表示当缓冲队列满的时候能继续容纳的等待任务的数量
26     private int maxPoolSize;
27     //存活时间
28     private long keepAliveTime = 1;
29     private TimeUnit unit = TimeUnit.HOURS;
30     private ThreadPoolExecutor executor;
31
32     private ThreadPoolUtil() {
33         //给corePoolSize赋值:当前设备可用处理器核心数*2 + 1,能够让cpu的效率得到最大程度执行(有研究论证的)
34         corePoolSize = Runtime.getRuntime().availableProcessors() * 2 + 1;
35         maxPoolSize = corePoolSize;
36         executor = new ThreadPoolExecutor(
37                 //当某个核心任务执行完毕,会依次从缓冲队列中取出等待任务
38                 corePoolSize,
39                 // 然后new LinkedBlockingQueue(),然后maximumPoolSize,但是它的数量是包含了corePoolSize的
40                 maxPoolSize,
41                 //表示的是maximumPoolSize当中等待任务的存活时间
42                 keepAliveTime,
43                 unit,
44                 //缓冲队列,用于存放等待任务,Linked的先进先出
45                 new LinkedBlockingQueue(),
46                 new DefaultThreadFactory(Thread.NORM_PRIORITY, "thread-pool-"),
47                 new ThreadPoolExecutor.AbortPolicy()
48         );
49     }
50
51     public static ThreadPoolUtil getInstance() {
52         if (mInstance == null) {
53             synchronized (ThreadPoolUtil.class) {
54                 if (mInstance == null) {
55                     mInstance = new ThreadPoolUtil();
56                 }
57             }
58         }
59         return mInstance;
60     }
61
62     /**
63      * 执行任务
64      *
65      * @param runnable
66      */
67     public void execute(Runnable runnable) {
68         if (executor == null) {
69             executor = new ThreadPoolExecutor(
70                     corePoolSize,
71                     maxPoolSize,
72                     keepAliveTime,
73                     TimeUnit.SECONDS,
74                     new LinkedBlockingQueue(),
75                     new DefaultThreadFactory(Thread.NORM_PRIORITY, "thread-pool-"),
76                     new ThreadPoolExecutor.AbortPolicy());
77         }
78         if (runnable != null) {
79             executor.execute(runnable);
80         }
81     }
82
83     /**
84      * 移除任务
85      *
86      * @param runnable
87      */
88     public void remove(Runnable runnable) {
89         if (runnable != null) {
90             executor.remove(runnable);
91         }
92     }
93
94     private static class DefaultThreadFactory implements ThreadFactory {
95         //线程池的计数
96         private static final AtomicInteger poolNumber = new AtomicInteger(1);
97         //线程的计数
98         private final AtomicInteger threadNumber = new AtomicInteger(1);
99         private final ThreadGroup group;
100         private final String namePrefix;
101         private final int threadPriority;
102
103         DefaultThreadFactory(int threadPriority, String threadNamePrefix) {
104             this.threadPriority = threadPriority;
105             this.group = Thread.currentThread().getThreadGroup();
106             this.namePrefix = threadNamePrefix + poolNumber.getAndIncrement() + "-thread-";
107         }
108
109         @Override
110         public Thread newThread(@NotNull Runnable r) {
111             Thread thread = new Thread(group, r, namePrefix + threadNumber.getAndIncrement(), 0);
112             // 返回True该线程就是守护线程
113             // 守护线程应该永远不去访问固有资源,如:数据库、文件等。因为它会在任何时候甚至在一个操作的中间发生中断。
114             if (thread.isDaemon()) {
115                 thread.setDaemon(false);
116             }
117             thread.setPriority(threadPriority);
118             return thread;
119         }
120     }
121 }