From 4aef88313cb076a124acfa6c2e3f2cf8d3136fba Mon Sep 17 00:00:00 2001 From: yennanliu Date: Tue, 9 Jul 2024 17:51:02 +0800 Subject: [PATCH 1/3] add ThreadPoolConfig --- .../yen/mdblog/config/ThreadPoolConfig.java | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 springBootBlog/src/main/java/com/yen/mdblog/config/ThreadPoolConfig.java diff --git a/springBootBlog/src/main/java/com/yen/mdblog/config/ThreadPoolConfig.java b/springBootBlog/src/main/java/com/yen/mdblog/config/ThreadPoolConfig.java new file mode 100644 index 000000000..ea6e01d35 --- /dev/null +++ b/springBootBlog/src/main/java/com/yen/mdblog/config/ThreadPoolConfig.java @@ -0,0 +1,36 @@ +package com.yen.mdblog.config; + +// https://blog.csdn.net/u010986241/article/details/138205146 + +import org.springframework.context.annotation.Bean; +import org.springframework.context.annotation.Configuration; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; + +import java.util.concurrent.ThreadPoolExecutor; + +@Configuration +public class ThreadPoolConfig { + + int CORE_POOL_SIZE = 5; + int MAX_POOL_SIZE = 10; + int QUEUE_CAPACITY = 20; + int KEEP_ALIVE_SECONDS = 30; + String THREAD_NAME_PREFIX = "custom-thread-x-"; + + @Bean(name="customThreadPool") + public ThreadPoolTaskExecutor threadPoolExecutor(){ + + System.out.println(">>>> ThreadPoolConfig init"); + ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); + + executor.setCorePoolSize(CORE_POOL_SIZE); + executor.setMaxPoolSize(MAX_POOL_SIZE); + executor.setQueueCapacity(QUEUE_CAPACITY); + executor.setKeepAliveSeconds(KEEP_ALIVE_SECONDS); + executor.setThreadNamePrefix(THREAD_NAME_PREFIX); + executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); + + return executor; + } + +} From aa75af11164d1e4f59adc403ef6acd0cd75aa5d9 Mon Sep 17 00:00:00 2001 From: yennanliu Date: Tue, 9 Jul 2024 18:15:37 +0800 Subject: [PATCH 2/3] disable AuthorServiceImpl, add multi thread method in AsyncAuthorServiceImpl, add exception to method --- .../mdblog/controller/AuthorController.java | 6 +- .../controller/AuthorEditController.java | 8 +- .../yen/mdblog/controller/PostController.java | 3 +- .../com/yen/mdblog/service/AuthorService.java | 5 +- .../service/impl/AsyncAuthorServiceImpl.java | 81 ++++++++++++ .../service/impl/AuthorServiceImpl.java | 122 +++++++++--------- 6 files changed, 158 insertions(+), 67 deletions(-) create mode 100644 springBootBlog/src/main/java/com/yen/mdblog/service/impl/AsyncAuthorServiceImpl.java diff --git a/springBootBlog/src/main/java/com/yen/mdblog/controller/AuthorController.java b/springBootBlog/src/main/java/com/yen/mdblog/controller/AuthorController.java index 6e5b820a3..f5c5eaf92 100644 --- a/springBootBlog/src/main/java/com/yen/mdblog/controller/AuthorController.java +++ b/springBootBlog/src/main/java/com/yen/mdblog/controller/AuthorController.java @@ -4,6 +4,8 @@ import com.yen.mdblog.service.AuthorService; import java.security.Principal; import java.util.List; +import java.util.concurrent.ExecutionException; + import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @@ -20,7 +22,7 @@ public class AuthorController { @Autowired AuthorService authorService; @GetMapping("/all") - String getAllAuthor(Model model, Principal principal) { + String getAllAuthor(Model model, Principal principal) throws ExecutionException, InterruptedException { List authors = authorService.getAllAuthors(); model.addAttribute("authors", authors); @@ -29,7 +31,7 @@ String getAllAuthor(Model model, Principal principal) { } @GetMapping("/{id}") - public String getAuthorById(@PathVariable Integer id, Model model, Principal principal) { + public String getAuthorById(@PathVariable Integer id, Model model, Principal principal) throws ExecutionException, InterruptedException { Author author = authorService.getById(id); model.addAttribute("author", author); diff --git a/springBootBlog/src/main/java/com/yen/mdblog/controller/AuthorEditController.java b/springBootBlog/src/main/java/com/yen/mdblog/controller/AuthorEditController.java index f7cc31de1..1582bef38 100644 --- a/springBootBlog/src/main/java/com/yen/mdblog/controller/AuthorEditController.java +++ b/springBootBlog/src/main/java/com/yen/mdblog/controller/AuthorEditController.java @@ -10,6 +10,8 @@ import com.yen.mdblog.service.AuthorService; import java.security.Principal; import java.util.List; +import java.util.concurrent.ExecutionException; + import lombok.extern.log4j.Log4j2; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Controller; @@ -43,6 +45,10 @@ public String preEdit(Model model, Principal principal) { authorList = authorService.getAllAuthors(); pageInfo = new PageInfo(authorList, PageConst.PAGE_SIZE.getSize()); model.addAttribute("pageInfo", pageInfo); + } catch (ExecutionException e) { + throw new RuntimeException(e); + } catch (InterruptedException e) { + throw new RuntimeException(e); } finally { PageHelper.clearPage(); } @@ -66,7 +72,7 @@ public String editAuthor(Model model, Principal principal) { } @GetMapping("/{id}") - public String getAuthorById(@PathVariable Integer id, Model model, Principal principal) { + public String getAuthorById(@PathVariable Integer id, Model model, Principal principal) throws ExecutionException, InterruptedException { Author author = authorService.getById(id); model.addAttribute("author", author); diff --git a/springBootBlog/src/main/java/com/yen/mdblog/controller/PostController.java b/springBootBlog/src/main/java/com/yen/mdblog/controller/PostController.java index 6a1537ae1..3bf47168a 100644 --- a/springBootBlog/src/main/java/com/yen/mdblog/controller/PostController.java +++ b/springBootBlog/src/main/java/com/yen/mdblog/controller/PostController.java @@ -21,6 +21,7 @@ import java.util.Date; import java.util.List; import java.util.Optional; +import java.util.concurrent.ExecutionException; import java.util.stream.Collectors; import lombok.extern.log4j.Log4j2; import org.springframework.beans.BeanUtils; @@ -125,7 +126,7 @@ public String createPostForm(Model model, Principal principal) { } @RequestMapping(value = "/create", method = RequestMethod.POST) - public String createPost(CreatePost request, Model model, Principal principal) { + public String createPost(CreatePost request, Model model, Principal principal) throws ExecutionException, InterruptedException { log.info(">>> create post start ..."); Post post = new Post(); diff --git a/springBootBlog/src/main/java/com/yen/mdblog/service/AuthorService.java b/springBootBlog/src/main/java/com/yen/mdblog/service/AuthorService.java index 11eb18ad0..a183861e1 100644 --- a/springBootBlog/src/main/java/com/yen/mdblog/service/AuthorService.java +++ b/springBootBlog/src/main/java/com/yen/mdblog/service/AuthorService.java @@ -3,14 +3,15 @@ import com.yen.mdblog.entity.Po.Author; import java.util.List; +import java.util.concurrent.ExecutionException; public interface AuthorService { - Author getById(Integer id); + Author getById(Integer id) throws ExecutionException, InterruptedException; Author getByName(String name); - List getAllAuthors(); + List getAllAuthors() throws ExecutionException, InterruptedException; Boolean createAuthor(String name, String email); diff --git a/springBootBlog/src/main/java/com/yen/mdblog/service/impl/AsyncAuthorServiceImpl.java b/springBootBlog/src/main/java/com/yen/mdblog/service/impl/AsyncAuthorServiceImpl.java new file mode 100644 index 000000000..93362aadd --- /dev/null +++ b/springBootBlog/src/main/java/com/yen/mdblog/service/impl/AsyncAuthorServiceImpl.java @@ -0,0 +1,81 @@ +package com.yen.mdblog.service.impl; + +import com.yen.mdblog.entity.Po.Author; +import com.yen.mdblog.mapper.AuthorMapper; +import com.yen.mdblog.service.AuthorService; +import java.util.Date; +import java.util.List; +import java.util.concurrent.ExecutionException; +import java.util.concurrent.Future; + +import lombok.extern.log4j.Log4j2; +import org.springframework.beans.factory.annotation.Autowired; +import org.springframework.beans.factory.annotation.Qualifier; +import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; +import org.springframework.stereotype.Service; + +@Service +@Log4j2 +public class AsyncAuthorServiceImpl implements AuthorService { + + + /** Thread pool */ + @Autowired + @Qualifier("customThreadPool") + private ThreadPoolTaskExecutor threadPoolTaskExecutor; + + @Autowired AuthorMapper authorMapper; + + @Override + public Author getById(Integer id) throws ExecutionException, InterruptedException { + + Future author = threadPoolTaskExecutor.submit(() -> { + authorMapper.getById(id); + }); + //return authorMapper.getById(id); + return (Author) author.get(); + } + + @Override + public Author getByName(String name) { + + return authorMapper.getByName(name); + } + + @Override + public List getAllAuthors() throws ExecutionException, InterruptedException { + + Future allAuthors = threadPoolTaskExecutor.submit(() -> { + authorMapper.getAllAuthors(); + }); + + return (List) allAuthors.get(); + } + + @Override + public Boolean createAuthor(String name, String email) { + try { + Author newAuthor = new Author(); + int id = authorMapper.getAuthorCount() + 1; + newAuthor.setId(id); + newAuthor.setName(name); + newAuthor.setEmail(email); + newAuthor.setCreateTime(new Date()); + newAuthor.setUpdateTime(new Date()); + log.info("save author = " + newAuthor); + authorMapper.insertAuthor(newAuthor); + log.info("create new user OK ..."); + return true; + } catch (Exception e) { + log.error("createAuthor failed : " + e); + return false; + } + } + + @Override + public void updateAuthor(Author author) { + + authorMapper.updateAuthor(author); + } + +} diff --git a/springBootBlog/src/main/java/com/yen/mdblog/service/impl/AuthorServiceImpl.java b/springBootBlog/src/main/java/com/yen/mdblog/service/impl/AuthorServiceImpl.java index 573078bf5..712a2ba7e 100644 --- a/springBootBlog/src/main/java/com/yen/mdblog/service/impl/AuthorServiceImpl.java +++ b/springBootBlog/src/main/java/com/yen/mdblog/service/impl/AuthorServiceImpl.java @@ -1,61 +1,61 @@ -package com.yen.mdblog.service.impl; - -import com.yen.mdblog.entity.Po.Author; -import com.yen.mdblog.mapper.AuthorMapper; -import com.yen.mdblog.service.AuthorService; -import java.util.Date; -import java.util.List; -import lombok.extern.log4j.Log4j2; -import org.springframework.beans.factory.annotation.Autowired; -import org.springframework.stereotype.Service; - -@Service -@Log4j2 -public class AuthorServiceImpl implements AuthorService { - - @Autowired AuthorMapper authorMapper; - - @Override - public Author getById(Integer id) { - - return authorMapper.getById(id); - } - - @Override - public Author getByName(String name) { - - return authorMapper.getByName(name); - } - - @Override - public List getAllAuthors() { - - return authorMapper.getAllAuthors(); - } - - @Override - public Boolean createAuthor(String name, String email) { - try { - Author newAuthor = new Author(); - int id = authorMapper.getAuthorCount() + 1; - newAuthor.setId(id); - newAuthor.setName(name); - newAuthor.setEmail(email); - newAuthor.setCreateTime(new Date()); - newAuthor.setUpdateTime(new Date()); - log.info("save author = " + newAuthor); - authorMapper.insertAuthor(newAuthor); - log.info("create new user OK ..."); - return true; - } catch (Exception e) { - log.error("createAuthor failed : " + e); - return false; - } - } - - @Override - public void updateAuthor(Author author) { - - authorMapper.updateAuthor(author); - } -} +//package com.yen.mdblog.service.impl; +// +//import com.yen.mdblog.entity.Po.Author; +//import com.yen.mdblog.mapper.AuthorMapper; +//import com.yen.mdblog.service.AuthorService; +//import java.util.Date; +//import java.util.List; +//import lombok.extern.log4j.Log4j2; +//import org.springframework.beans.factory.annotation.Autowired; +//import org.springframework.stereotype.Service; +// +//@Service +//@Log4j2 +//public class AuthorServiceImpl implements AuthorService { +// +// @Autowired AuthorMapper authorMapper; +// +// @Override +// public Author getById(Integer id) { +// +// return authorMapper.getById(id); +// } +// +// @Override +// public Author getByName(String name) { +// +// return authorMapper.getByName(name); +// } +// +// @Override +// public List getAllAuthors() { +// +// return authorMapper.getAllAuthors(); +// } +// +// @Override +// public Boolean createAuthor(String name, String email) { +// try { +// Author newAuthor = new Author(); +// int id = authorMapper.getAuthorCount() + 1; +// newAuthor.setId(id); +// newAuthor.setName(name); +// newAuthor.setEmail(email); +// newAuthor.setCreateTime(new Date()); +// newAuthor.setUpdateTime(new Date()); +// log.info("save author = " + newAuthor); +// authorMapper.insertAuthor(newAuthor); +// log.info("create new user OK ..."); +// return true; +// } catch (Exception e) { +// log.error("createAuthor failed : " + e); +// return false; +// } +// } +// +// @Override +// public void updateAuthor(Author author) { +// +// authorMapper.updateAuthor(author); +// } +//} From b98c1abbc490dfaec5a244b0963946a19997eb44 Mon Sep 17 00:00:00 2001 From: yennanliu Date: Tue, 9 Jul 2024 18:31:51 +0800 Subject: [PATCH 3/3] fix return res so Future can get res and return as api reso --- .../service/impl/AsyncAuthorServiceImpl.java | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/springBootBlog/src/main/java/com/yen/mdblog/service/impl/AsyncAuthorServiceImpl.java b/springBootBlog/src/main/java/com/yen/mdblog/service/impl/AsyncAuthorServiceImpl.java index 93362aadd..de6f9c88a 100644 --- a/springBootBlog/src/main/java/com/yen/mdblog/service/impl/AsyncAuthorServiceImpl.java +++ b/springBootBlog/src/main/java/com/yen/mdblog/service/impl/AsyncAuthorServiceImpl.java @@ -29,11 +29,14 @@ public class AsyncAuthorServiceImpl implements AuthorService { @Override public Author getById(Integer id) throws ExecutionException, InterruptedException { - Future author = threadPoolTaskExecutor.submit(() -> { - authorMapper.getById(id); + Future futureAuthor = threadPoolTaskExecutor.submit(() -> { + + System.out.println("--> Thread name : " + Thread.currentThread().getName() + ", id = " + Thread.currentThread().getId()); + + return authorMapper.getById(id); // Assuming authorMapper.getById(id) returns Author }); - //return authorMapper.getById(id); - return (Author) author.get(); + + return futureAuthor.get(); // This will block until the result is available } @Override @@ -42,14 +45,19 @@ public Author getByName(String name) { return authorMapper.getByName(name); } + @Override public List getAllAuthors() throws ExecutionException, InterruptedException { - Future allAuthors = threadPoolTaskExecutor.submit(() -> { - authorMapper.getAllAuthors(); - }); + Future> allAuthors = threadPoolTaskExecutor.submit(() -> { + + System.out.println("--> Thread name : " + Thread.currentThread().getName() + ", id = " + Thread.currentThread().getId()); + + return authorMapper.getAllAuthors(); + } + ); - return (List) allAuthors.get(); + return allAuthors.get(); } @Override