diff --git a/waynboot-data/waynboot-data-redis/src/main/java/com/wayn/data/redis/manager/RedisCache.java b/waynboot-data/waynboot-data-redis/src/main/java/com/wayn/data/redis/manager/RedisCache.java index e78f135..94e0519 100644 --- a/waynboot-data/waynboot-data-redis/src/main/java/com/wayn/data/redis/manager/RedisCache.java +++ b/waynboot-data/waynboot-data-redis/src/main/java/com/wayn/data/redis/manager/RedisCache.java @@ -90,6 +90,17 @@ public class RedisCache { return operation.get(key); } + /** + * 获取多个key的 + * + * @param keys 多个key组成的集合 + * @return 多个key对应的value + */ + public List mGetCacheObject(Collection keys) { + ValueOperations operation = redisTemplate.opsForValue(); + return operation.multiGet(keys); + } + /** * 删除单个对象 * diff --git a/waynboot-mobile-api/src/main/java/com/wayn/mobile/api/service/IHomeService.java b/waynboot-mobile-api/src/main/java/com/wayn/mobile/api/service/IHomeService.java index cd5e1a5..e22e60e 100644 --- a/waynboot-mobile-api/src/main/java/com/wayn/mobile/api/service/IHomeService.java +++ b/waynboot-mobile-api/src/main/java/com/wayn/mobile/api/service/IHomeService.java @@ -6,16 +6,6 @@ import com.wayn.common.util.R; public interface IHomeService { - /** - * 获取首页数据(bannerList,category List,newGoodsList,hotGoodsList),
- * 采用Future方式,可以异步计算返回结果,但是对于结果的获取却是很不方便,只能通过阻塞或者轮询的方式得到任务的结果,
- * 区别详情见下方链接 - * - * @return r - * @see https://www.cnblogs.com/cjsblog/p/9267163.html - */ - R getHomeIndexData(); - /** * 获取首页数据(bannerList,category List,newGoodsList,hotGoodsList)
* 采用CompletableFuture方式 diff --git a/waynboot-mobile-api/src/main/java/com/wayn/mobile/api/service/impl/IHomeServiceImpl.java b/waynboot-mobile-api/src/main/java/com/wayn/mobile/api/service/impl/IHomeServiceImpl.java index 9d5d6a7..493a060 100644 --- a/waynboot-mobile-api/src/main/java/com/wayn/mobile/api/service/impl/IHomeServiceImpl.java +++ b/waynboot-mobile-api/src/main/java/com/wayn/mobile/api/service/impl/IHomeServiceImpl.java @@ -13,115 +13,76 @@ import com.wayn.common.core.service.shop.IGoodsService; import com.wayn.common.util.R; import com.wayn.data.redis.manager.RedisCache; import com.wayn.mobile.api.service.IHomeService; +import lombok.AllArgsConstructor; import lombok.extern.slf4j.Slf4j; -import org.springframework.beans.factory.annotation.Autowired; import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor; import org.springframework.stereotype.Service; import java.util.ArrayList; import java.util.List; -import java.util.concurrent.*; +import java.util.concurrent.CompletableFuture; +import java.util.concurrent.TimeUnit; @Slf4j @Service +@AllArgsConstructor public class IHomeServiceImpl implements IHomeService { - private static final String INDEX_DATA = "shop_index_data"; + private static final String SHOP_INDEX_BANNER_LIST = "shop_index_banner_list"; + private static final String SHOP_INDEX_CATEGORY_LIST = "shop_index_category_list"; + private static final String SHOP_INDEX_GOODS_NEW_LIST = "shop_index_goods_new_list"; + private static final String SHOP_INDEX_GOODS_HOT_LIST = "shop_index_goods_hot_list"; - @Autowired private IBannerService iBannerService; - - @Autowired private ICategoryService iCategoryService; - - @Autowired private IGoodsService iGoodsService; - - @Autowired private RedisCache redisCache; - - @Autowired private IDiamondService iDiamondService; - - @Autowired private ThreadPoolTaskExecutor threadPoolTaskExecutor; - @Override - public R getHomeIndexData() { - if (redisCache.existsKey(INDEX_DATA)) { - return redisCache.getCacheObject(INDEX_DATA); - } - R success = R.success(); - Callable> bannerCall = () -> iBannerService.list(new QueryWrapper().eq("status", 0).orderByAsc("sort")); - Callable> diamondCall = () -> iDiamondService.list(new QueryWrapper() - .orderByAsc("sort") - .last("limit 10")); - Callable> newGoodsCall = () -> iGoodsService.list(new QueryWrapper() - .eq("is_new", true) - .eq("is_on_sale", true) - .orderByAsc("create_time") - .last("limit 6")); - Callable> hotGoodsCall = () -> iGoodsService.list(new QueryWrapper() - .eq("is_hot", true) - .eq("is_on_sale", true) - .orderByAsc("create_time") - .last("limit 6")); - FutureTask> bannerTask = new FutureTask<>(bannerCall); - FutureTask> diamondTask = new FutureTask<>(diamondCall); - FutureTask> newGoodsTask = new FutureTask<>(newGoodsCall); - FutureTask> hotGoodsTask = new FutureTask<>(hotGoodsCall); - threadPoolTaskExecutor.submit(bannerTask); - threadPoolTaskExecutor.submit(diamondTask); - threadPoolTaskExecutor.submit(newGoodsTask); - threadPoolTaskExecutor.submit(hotGoodsTask); - try { - success.add("bannerList", bannerTask.get()); - success.add("categoryList", diamondTask.get()); - success.add("newGoodsList", newGoodsTask.get()); - success.add("hotGoodsList", hotGoodsTask.get()); - redisCache.setCacheObject(INDEX_DATA, success, 10, TimeUnit.MINUTES); - } catch (InterruptedException | ExecutionException e) { - log.error(e.getMessage(), e); - } finally { - threadPoolTaskExecutor.shutdown(); - } - return success; - } - @Override public R getHomeIndexDataCompletableFuture() { - if (redisCache.existsKey(INDEX_DATA)) { - return redisCache.getCacheObject(INDEX_DATA); - } R success = R.success(); - List> list = new ArrayList<>(); + + List> list = new ArrayList<>(4); CompletableFuture f1 = CompletableFuture.supplyAsync(() -> iBannerService.list(new QueryWrapper() - .eq("status", 0) - .orderByAsc("sort"))) - .thenAccept(data -> success.add("bannerList", data)); + .eq("status", 0) + .orderByAsc("sort")), threadPoolTaskExecutor) + .thenAccept(data -> { + redisCache.setCacheObject(SHOP_INDEX_BANNER_LIST, data, 3600, TimeUnit.MINUTES); + success.add("bannerList", data); + }); CompletableFuture f2 = CompletableFuture.supplyAsync(() -> iDiamondService.list(new QueryWrapper() - .orderByAsc("sort") - .last("limit 10"))) - .thenAccept(data -> success.add("categoryList", data)); + .orderByAsc("sort") + .last("limit 10")), threadPoolTaskExecutor) + .thenAccept(data -> { + redisCache.setCacheObject(SHOP_INDEX_CATEGORY_LIST, data, 3600, TimeUnit.MINUTES); + success.add("categoryList", data); + }); CompletableFuture f3 = CompletableFuture.supplyAsync(() -> iGoodsService.list(new QueryWrapper() - .eq("is_new", true) - .eq("is_on_sale", true) - .orderByAsc("create_time") - .last("limit 6"))) - .thenAccept(data -> success.add("newGoodsList", data)); + .eq("is_new", true) + .eq("is_on_sale", true) + .orderByAsc("create_time") + .last("limit 6")), threadPoolTaskExecutor) + .thenAccept(data -> { + redisCache.setCacheObject(SHOP_INDEX_GOODS_NEW_LIST, data, 3600, TimeUnit.MINUTES); + success.add("newGoodsList", data); + }); CompletableFuture f4 = CompletableFuture.supplyAsync(() -> iGoodsService.list(new QueryWrapper() - .eq("is_hot", true) - .eq("is_on_sale", true) - .orderByAsc("create_time") - .last("limit 6"))) - .thenAccept(data -> success.add("hotGoodsList", data)); + .eq("is_hot", true) + .eq("is_on_sale", true) + .orderByAsc("create_time") + .last("limit 6")), threadPoolTaskExecutor) + .thenAccept(data -> { + redisCache.setCacheObject(SHOP_INDEX_GOODS_HOT_LIST, data, 3600, TimeUnit.MINUTES); + success.add("hotGoodsList", data); + }); list.add(f1); list.add(f2); list.add(f3); list.add(f4); CompletableFuture.allOf(list.toArray(new CompletableFuture[0])).join(); - redisCache.setCacheObject(INDEX_DATA, success, 3600, TimeUnit.MINUTES); return success; } diff --git a/waynboot-mobile-api/src/main/java/com/wayn/mobile/framework/config/ThreadPoolConfig.java b/waynboot-mobile-api/src/main/java/com/wayn/mobile/framework/config/ThreadPoolConfig.java index f386b03..808a246 100644 --- a/waynboot-mobile-api/src/main/java/com/wayn/mobile/framework/config/ThreadPoolConfig.java +++ b/waynboot-mobile-api/src/main/java/com/wayn/mobile/framework/config/ThreadPoolConfig.java @@ -16,13 +16,13 @@ import java.util.concurrent.ThreadPoolExecutor; @Configuration public class ThreadPoolConfig { // 核心线程池大小 - private int corePoolSize = 200; + private int corePoolSize = 10; // 最大可创建的线程数 - private int maxPoolSize = 400; + private int maxPoolSize = 100; // 队列最大长度 - private int queueCapacity = 1000; + private int queueCapacity = 200; // 线程池维护线程所允许的空闲时间 private int keepAliveSeconds = 300; @@ -34,6 +34,7 @@ public class ThreadPoolConfig { executor.setCorePoolSize(corePoolSize); executor.setQueueCapacity(queueCapacity); executor.setKeepAliveSeconds(keepAliveSeconds); + executor.setThreadNamePrefix("homeIndexThread-"); // 线程池对拒绝任务(无线程可用)的处理策略 executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy()); return executor;