线程池的理解
博客摘抄自 : https://www.cnblogs.com/Krloypower/p/9848018.html
线程池
在项目中提前创建好几个线程,当有任务来的时候,直接用创建好的线程来处理任务,处理完之后,线程不会销毁,等待下一个任务。由于创建和销毁线程很消耗性能。所以可以用线程池来提高性能。
自己踏入过的误区,在一个类里面,把线程池当作了改类的成员变量,用完之后没有shutdown。
eg1:
// 错误写法 public class test{ private ThreadPoolExecutor excutor ...... }
每次新建改对象,都会创建一个线程池,这样会导致资源耗尽,出现OOM。
eg2:
误区2 ,在一个类中,设置一个静态变量的线程池,这个类共用一个线程池。用完之后没有shutdown。
// 错误写法 public class test{ private static ThreadPoolExecutor excutor ...... }
这样的写法有点狭隘,只在当前类中,浪费资源。
要补充的是,若是使用线程池资源的话,就不用shutdown线程了。shutdown只是给队列的线程发interrupt 不能接受新任务 但等待老任务结束 。
其实这个要看具体情况而言,比如对于一类资源使用一个线程池,然后不关闭掉。在关服之前关闭掉线程池,在比如1到2点接受任务,2点之后不接受任务,那么2点关闭掉线程池等等。
public ThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler)
- corePoolSize : 核心池大小,线程池允许的线程数量
- maximumPoolSize:最大池大小,当核心池中的线程数量满了,并且BlockingQueue队列已满,这个时候又来了一个任务。就会新建一个线程执行该任务,一直到线程池的线程数量达到maximumPoolSize大小,如果这时再来一个任务,就会调用相应的拒绝策略。当线程池的任务降低到只需要corePoolSize的线程数一下,就会根据keepAliveTime ,回收大于corePoolSize的多余的线程。
- keepAliveTime:当线程池中的数据大于corePoolSize时,多余的线程没有任务进来的时候,根据这个时间大小回收。
- unit:回收时间大小
- workQueue:阻塞队列类型
- threadFactory:线程池工程
- handler:拒绝策略
public class ThreadPoolExecutorUtil { // 线程池 单例化:全局唯一配置 private static final ThreadPoolExecutor executor = new ThreadPoolExecutor(10,20, 60L,TimeUnit.SECONDS, new SynchronousQueue<>(),Executors.defaultThreadFactory(), new ThreadPoolExecutor.AbortPolicy()); public ThreadPoolExecutorUtil(){}; public static ThreadPoolExecutor getInstance(){ return executor; } }
其实,为了线程安全,上面的Thread是典型的饿汉式的,线程是安全的,我们还可以把初始化工作也完成掉,直接在启动类的下方加上此static的实例化:
public static void main(String[] args) { ConfigurableApplicationContext configurableApplicationContext = SpringApplication.run(ReportServerApplication.class, args); // 解决websocket 当中无法注入bean的方法 ImportDictValueSocket.setApplicationContext(configurableApplicationContext); ThreadPoolExecutorUtil.getInstance(); // 让其直接实例化掉 }

浙公网安备 33010602011771号