In addition to Weibo, there is also WeChat
Please pay attention
WeChat public account
Shulou
2025-03-28 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >
Share
Shulou(Shulou.com)06/02 Report--
This article mainly introduces how to use SpringBoot multithreading @ Async, has a certain reference value, interested friends can refer to, I hope you can learn a lot after reading this article, the following let the editor take you to understand it.
Experience scenario of multithreading @ Async
Import: large quantities of data insert operations can be executed in parallel in a multithreaded manner
Interface invocation of third-party services: since individual third-party service invocations are time-consuming, they can be executed in parallel with the logic of their own services.
In short: the business logic in the middle of the interface can optimize the performance of the interface in parallel
1. Thread pool configuration @ Configuration@EnableAsyncpublic class TaskPoolConfig {@ Bean ("taskExecutor") / / bean. Default is the lowercase method name public Executor taskExecutor () {ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor (); / / number of core threads (CPU cores + 1) executor.setCorePoolSize (10); / / maximum number of threads (2*CPU cores + 1) executor.setMaxPoolSize (20) / / buffer queues executor.setQueueCapacity (200); / allow idle time of threads (in seconds by default) executor.setKeepAliveSeconds (60); / / prefix executor.setThreadNamePrefix of thread pool name ("sub-thread-"); / / add configuration executor.setTaskDecorator for TaskDecorator attribute (new ContextDecorator ()) / / Thread pool's strategy for rejecting tasks: CallerRunsPolicy: instead of executing the task in the new thread, the caller's thread executes executor.setRejectedExecutionHandler (new ThreadPoolExecutor.CallerRunsPolicy ()); executor.initialize (); return executor;}} 2. Configuration scheme for sharing a Request between child parent threads
1. Implement the TaskDecorator interface
/ * child thread decorator * * @ author Da Shuai * @ date 2021-06-10 18:28:17 * / public class SubThreadTaskDecorator implements TaskDecorator {@ Override public Runnable decorate (Runnable runnable) {RequestAttributes context = RequestContextHolder.currentRequestAttributes (); return ()-> {try {RequestContextHolder.setRequestAttributes (context); runnable.run () } finally {RequestContextHolder.resetRequestAttributes ();}};}}
two。 The previous thread pool configuration takes effect with the following code
/ / add the configuration executor.setTaskDecorator (new ContextDecorator ()) of TaskDecorator attribute; 3. Block the main thread and wait for all child threads to finish execution and continue to execute the main thread 1.CountDownLatch
Train of thought:
Instantiate the CountDownLatch object and pass in x (number of threads: this number must be equal to the number of child threads) to construct
The countDown () method is called after each child thread finishes execution.
The await () method is called after the child thread logic
In this way, the main thread is in the pending state until the thread counter is 0
Main thread logic
New CountDownLatch (X) latch.await () @ Override@Transactionalpublic void importExcel (File file) {CountDownLatch latch = new CountDownLatch (3); for (int I = 0; I
< 3; i++) { VoteDO voteDO = new VoteDO(); voteDO.setTitle(i + ""); asyncManager.asyncSaveVote(voteDO); } //System.out.println(1/0); try { latch.await(); } catch (InterruptedException e) { e.printStackTrace(); }} 子线程逻辑 latch.countDown()@Override@Asyncpublic void asyncSaveVote(VoteDO voteDO, CountDownLatch latch) { log.info("当前线程为 {},休眠10s开始", Thread.currentThread().getName()); try { Thread.sleep(10000L); } catch (InterruptedException e) { e.printStackTrace(); } log.info("当前线程为 {},休眠10s结束", Thread.currentThread().getName()); log.info("当前线程为 {},保存开始", Thread.currentThread().getName()); voteDO.setDesc(Thread.currentThread().getName()); voteDao.insert(voteDO); latch.countDown(); log.info("当前线程为 {},保存结束", Thread.currentThread().getName());} 日志 2021-06-11 16:31:08.653 INFO 27516 --- [nio-8080-exec-1] com.zhdj.config.LogAspect : ===============请求内容=============== 2021-06-11 16:31:08.653 INFO 27516 --- [nio-8080-exec-1] com.zhdj.config.LogAspect : 请求地址:http://localhost:8080/api/import 2021-06-11 16:31:08.653 INFO 27516 --- [nio-8080-exec-1] com.zhdj.config.LogAspect : 请求方式:POST 2021-06-11 16:31:08.655 INFO 27516 --- [nio-8080-exec-1] com.zhdj.config.LogAspect : 请求类方法:com.zhdj.controller.ImportController.importExcel 2021-06-11 16:31:08.655 INFO 27516 --- [nio-8080-exec-1] com.zhdj.config.LogAspect : 请求类方法参数:[org.springframework.web.multipart.support.StandardMultipartHttpServletRequest$StandardMultipartFile@42c3f403] 2021-06-11 16:31:08.655 INFO 27516 --- [nio-8080-exec-1] com.zhdj.config.LogAspect : ===============请求内容=============== 2021-06-11 16:31:08.676 INFO 27516 --- [nio-8080-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Starting... 2021-06-11 16:31:08.894 INFO 27516 --- [nio-8080-exec-1] com.zaxxer.hikari.HikariDataSource : HikariPool-1 - Start completed. 2021-06-11 16:31:08.921 INFO 27516 --- [ sub-thread-3] com.zhdj.AsyncManagerImpl : 当前线程为 sub-thread-3,休眠10s开始 2021-06-11 16:31:08.921 INFO 27516 --- [ sub-thread-1] com.zhdj.AsyncManagerImpl : 当前线程为 sub-thread-1,休眠10s开始 2021-06-11 16:31:08.921 INFO 27516 --- [ sub-thread-2] com.zhdj.AsyncManagerImpl : 当前线程为 sub-thread-2,休眠10s开始 2021-06-11 16:31:18.921 INFO 27516 --- [ sub-thread-2] com.zhdj.AsyncManagerImpl : 当前线程为 sub-thread-2,休眠10s结束 2021-06-11 16:31:18.921 INFO 27516 --- [ sub-thread-3] com.zhdj.AsyncManagerImpl : 当前线程为 sub-thread-3,休眠10s结束 2021-06-11 16:31:18.921 INFO 27516 --- [ sub-thread-2] com.zhdj.AsyncManagerImpl : 当前线程为 sub-thread-2,保存开始 2021-06-11 16:31:18.921 INFO 27516 --- [ sub-thread-1] com.zhdj.AsyncManagerImpl : 当前线程为 sub-thread-1,休眠10s结束 2021-06-11 16:31:18.921 INFO 27516 --- [ sub-thread-3] com.zhdj.AsyncManagerImpl : 当前线程为 sub-thread-3,保存开始 2021-06-11 16:31:18.921 INFO 27516 --- [ sub-thread-1] com.zhdj.AsyncManagerImpl : 当前线程为 sub-thread-1,保存开始 2021-06-11 16:31:19.080 DEBUG 27516 --- [ sub-thread-3] com.zhdj.dao.VoteDao.insert : ==>Preparing: INSERT INTO vote (title, `room`, gmt_create, gmt_modified) VALUES (?)
2021-06-11 16 DEBUG 31V 19.080 DEBUG 27516-[sub-thread-1] com.zhdj.dao.VoteDao.insert: = > Preparing: INSERT INTO vote (title, `room`, gmt_create, gmt_modified) VALUES (?)
2021-06-11 16 DEBUG 31V 19.080 DEBUG 27516-[sub-thread-2] com.zhdj.dao.VoteDao.insert: = > Preparing: INSERT INTO vote (title, `room`, gmt_create, gmt_modified) VALUES (?)
2021-06-11 16 com.zhdj.dao.VoteDao.insert 31 DEBUG 19.156 27516-[sub-thread-1] com.zhdj.dao.VoteDao.insert: = > Parameters: 0 (String), sub-thread-1 (String), 2021-06-11T16:31:19.032 (LocalDateTime), 2021-06-11T16:31:19.037 (LocalDateTime)
2021-06-11 16 com.zhdj.dao.VoteDao.insert 31 DEBUG 19.156 27516-[sub-thread-3] com.zhdj.dao.VoteDao.insert: = > Parameters: 2 (String), sub-thread-3 (String), 2021-06-11T16:31:19.032 (LocalDateTime), 2021-06-11T16:31:19.037 (LocalDateTime)
2021-06-11 16 com.zhdj.dao.VoteDao.insert 31 DEBUG 19.156 27516-[sub-thread-2] com.zhdj.dao.VoteDao.insert: = > Parameters: 1 (String), sub-thread-2 (String), 2021-06-11T16:31:19.032 (LocalDateTime), 2021-06-11T16:31:19.037 (LocalDateTime)
2021-06-11 16 DEBUG 31 com.zhdj.dao.VoteDao.insert 19.172 DEBUG 27516-[sub-thread-3] com.zhdj.dao.VoteDao.insert: Preparing: INSERT INTO vote (title, `room`, gmt_create, gmt_modified) VALUES (?)
2021-06-11 16 DEBUG 42 DEBUG 20492-[sub-thread-5] com.zhdj.dao.VoteDao.insert: = = > Parameters: 1 (String), sub-thread-5 (String), 2021-06-11T16:42:38.980 (LocalDateTime), 2021-06-11T16:42:38.981 (LocalDateTime)
2021-06-11 16 DEBUG 42 DEBUG 20492-[sub-thread-4] com.zhdj.dao.VoteDao.insert: = > Parameters: 0 (String), sub-thread-4 (String), 2021-06-11T16:42:38.980 (LocalDateTime), 2021-06-11T16:42:38.981 (LocalDateTime)
2021-06-11 16 DEBUG 42 DEBUG 20492-[sub-thread-6] com.zhdj.dao.VoteDao.insert: = > Parameters: 2 (String), sub-thread-6 (String), 2021-06-11T16:42:38.980 (LocalDateTime), 2021-06-11T16:42:38.981 (LocalDateTime)
2021-06-11 16 com.zhdj.dao.VoteDao.insert 42 com.zhdj.dao.VoteDao.insert 38.988 DEBUG 20492-[sub-thread-5]
Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.
Views: 0
*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.
Continue with the installation of the previous hadoop.First, install zookooper1. Decompress zookoope
"Every 5-10 years, there's a rare product, a really special, very unusual product that's the most un
© 2024 shulou.com SLNews company. All rights reserved.