linux 线程 前世今生,Spring Boot 线程池的前世今生

5aefd59a49855ddb781c5759b084c1c1.png

为什么需要线程池

当我们需要使用多个线程处理任务时,每个任务可以很快就执行完成,但是线程需要建立、销毁,非常消耗资源,也降低了效率,因此需要采用线程池,保留建立的线程、重复使用线程执行任务,会大大地提高效率。

JAVA SDK对线程的支持

从JAVA SDK 1.5版本开始,提供了Executor 接口来表示线程池,通过execute方法执行任务,另外 ExecutorService接口,实现了多线程池的管理方法,包括任务的提交、线程池关闭、是否关闭等方法。如下图:

详细说一下ExecutorService接口,它通过 submit方法提交一个任务执行,任务需要实现Runnable 接口,Runnable接口是一个包含run函数的接口。

通过shutdown方法可以等待线程池内任务执行后,关闭线程池。

通过shutdownNow方法不等待,直接关闭线程池。

如下代码所示:Runnable task = () -> {try {String threadName = Thread.currentThread().getName();TimeUnit.SECONDS.sleep(1);System.out.println(threadName);}catch(InterruptedException e){e.printStackTrace();}};ExecutorService service = Executors.newFixedThreadPool(5);try{service.submit(task);service.shutdown();service.awaitTermination(1,TimeUnit.SECONDS);}catch (Exception e){e.printStackTrace();}finally {if (!service.isTerminated()){System.err.println("Thread pool is not terminated");}service.shutdownNow();System.out.println("Thread poo is finish");}

Executors是在java.util.concurrent包中的创建线程池的工厂类,

提供了多种创建线程池对象的静态工厂方法。

如下图所示:

1046edad393e24b916fe7369da6a2f67.png

在Spring boot 中使用线程池

首先在application.yml配置文件中,增加线程池的配置信息,如下:app:pool:core-pool-size: 1max-pool-size: 2pool-queue-capacity: 500thread-name-prefix: opc-server-connection-thread

然后增加线程池配置类

注意在类定义前增加@EnableAsync 和@Component注解

在返回Executor的方法前面增加@Bean注解,并设置Bean的名称@ConfigurationProperties("app.pool")@EnableAsync@Component@Setter@Getterpublic class AppThreadPoolConfig {private Integer corePoolSize;private Integer maxPoolSize;private Integer poolQueueCapacity;private String threadNamePrefix;@Bean(name = "asyncServiceExecutor")public Executor asyncServiceExecutor() {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();//配置核心线程数executor.setCorePoolSize(corePoolSize);//配置最大线程数executor.setMaxPoolSize(maxPoolSize);//配置队列大小executor.setQueueCapacity(poolQueueCapacity);//配置线程池中的线程的名称前缀executor.setThreadNamePrefix(threadNamePrefix);// rejection-policy:当pool已经达到max size的时候,如何处理新任务// CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());//执行初始化executor.initialize();return executor;}}

最后,在需要使用线程池的地方获取线程池Bean,并提交任务。private Executor asyncServiceExecutor;asyncServiceExecutor = (Executor) ApplicationContextHelper.getBean("asyncServiceExecutor");asyncServiceExecutor.execute(()-> kafkaTemplate.send(kafkaTopicConfig.getTopicPrefix() + "_" + datasourceId, datasourceId.toString(), msg));

在上面的代码中,我们可以看到 使用 ThreadPoolTaskExecutor类进行线程池的建立,该类在org.springframework.scheduling.concurrent包中。

ThreadPoolTaskExecutor类实现了Executor 接口,如下图所示:

6fe4501dea52b493cf448cb9d34527b7.png

总结

本文探讨了为什么需要线程池、Java SDK对线程池的支持以及Spring Boot中如何使用线程池,有描述的不清楚的地方请留言互动交流。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值