一、controller
/**
* java并发查询数据实战 提高接口响应速度
* @param userId
* @return
*/
@GetMapping("/get/data")
@ResponseBody
public UserBehaviorDataDTO getUserData(Long userId) {
System.out.println("UserController的线程:" + Thread.currentThread());
long begin = System.currentTimeMillis();
UserBehaviorDataDTO userAggregatedResult = myFutureTask.getUserAggregatedResult(userId);
long end = System.currentTimeMillis();
System.out.println("===============总耗时:" + (end - begin) / 1000.0000 + "秒");
return userAggregatedResult;
}
二、MyFutureTask
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Component;
import javax.annotation.Resource;
import java.util.List;
import java.util.concurrent.*;
/**
* 一个页面有多达10个左右的一个用户行为数据,
* 比如:点赞数,发布文章数,点赞数,消息数,关注数,收藏数,粉丝数,卡券数,红包数等等!
*/
@Slf4j
@Component
public class MyFutureTask {
@Resource
UserService userService;
/**
* 核心线程 8 最大线程 20 保活时间30s 存储队列 10 有守护线程 拒绝策略:将超负荷任务回退到调用者
*/
private static ExecutorService executor = new ThreadPoolExecutor(20,
50,
30L,
TimeUnit.SECONDS,
new LinkedBlockingQueue<Runnable>(100),
Executors.defaultThreadFactory(),
new ThreadPoolExecutor.CallerRunsPolicy());
public UserBehaviorDataDTO getUserAggregatedResult(final Long userId) {
System.out.println("MyFutureTask的线程:" + Thread.currentThread());
try {
// 发布文章数
CompletableFuture<List<String>> articleCountFT = CompletableFuture.supplyAsync(() -> userService.countArticleCountByUserId(userId), executor);
// 点赞数
CompletableFuture<Long> LikeCountFT = CompletableFuture.supplyAsync(() -> userService.countLikeCountByUserId(userId), executor);
// 粉丝数
CompletableFuture<Long> fansCountFT = CompletableFuture.supplyAsync(() -> userService.countFansCountByUserId(userId), executor);
//消息数
CompletableFuture<Long> msgCountFT = CompletableFuture.supplyAsync(() -> userService.countMsgCountByUserId(userId), executor);
//收藏数
CompletableFuture<Long> collectCountFT = CompletableFuture.supplyAsync(() -> userService.countCollectCountByUserId(userId), executor);
//关注数
CompletableFuture<Long> followCountFT = CompletableFuture.supplyAsync(() -> userService.countFollowCountByUserId(userId), executor);
//红包数
CompletableFuture<Long> redBagCountFT = CompletableFuture.supplyAsync(() -> userService.countRedBagCountByUserId(userId), executor);
//卡券数
CompletableFuture<Long> couponCountFT = CompletableFuture.supplyAsync(() -> userService.countCouponCountByUserId(userId), executor);
// 聚合所有的查询 等所有的查询都查询完 时间为其中耗时最大的一条线程时间(也可以不用设置时间)
// CompletableFuture.allOf(articleCountFT, LikeCountFT, fansCountFT, msgCountFT, collectCountFT, followCountFT, redBagCountFT, couponCountFT);
CompletableFuture.allOf(articleCountFT, LikeCountFT, fansCountFT, msgCountFT, collectCountFT, followCountFT, redBagCountFT, couponCountFT).get(20, TimeUnit.SECONDS);
UserBehaviorDataDTO userBehaviorData = UserBehaviorDataDTO.builder().articleCount(articleCountFT.get())
.likeCount(LikeCountFT.get())
.fansCount(fansCountFT.get())
.msgCount(msgCountFT.get())
.collectCount(collectCountFT.get())
.followCount(followCountFT.get())
.redBagCount(redBagCountFT.get())
.couponCount(couponCountFT.get())
.build();
return userBehaviorData;
} catch (Exception e) {
log.error("get user behavior data error", e);
return new UserBehaviorDataDTO();
}
}
}
三、service
import java.util.List;
public interface UserService {
Long countFansCountByUserId(Long userId);
Long countMsgCountByUserId(Long userId);
Long countCollectCountByUserId(Long userId);
Long countFollowCountByUserId(Long userId);
Long countRedBagCountByUserId(Long userId);
Long countCouponCountByUserId(Long userId);
List<String> countArticleCountByUserId(Long userId);
Long countLikeCountByUserId(Long userId);
}
四、serviceImpl
package com.woniu.demo.concurrent;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.TimeUnit;
@Service
public class UserServiceImpl implements UserService {
@Override
public Long countFansCountByUserId(Long userId) {
try {
TimeUnit.SECONDS.sleep(10);
System.out.println("获取FansCount===睡眠:" + 10 + "s");
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println("UserService获取FansCount的线程 " + Thread.currentThread().getName());
return 520l;
}
@Override
public Long countMsgCountByUserId(Long userId) {
System.out.println("UserService获取MsgCount的线程 " + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(10);
System.out.println("获取MsgCount===睡眠:" + 10 + "s");
} catch (InterruptedException e) {
e.printStackTrace();
}
return 618L;
}
@Override
public Long countCollectCountByUserId(Long userId) {
System.out.println("UserService获取CollectCount的线程 " + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(10);
System.out.println("获取CollectCount==睡眠:" + 10 + "s");
} catch (InterruptedException e) {
e.printStackTrace();
}
return 6664L;
}
@Override
public Long countFollowCountByUserId(Long userId) {
System.out.println("UserService获取FollowCount的线程 " + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(10);
System.out.println("获取FollowCount===睡眠:" + 10 + "s");
} catch (InterruptedException e) {
e.printStackTrace();
}
return 102L;
}
@Override
public Long countRedBagCountByUserId(Long userId) {
System.out.println("UserService获取RedBagCount的线程 " + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(4);
System.out.println("获取RedBagCount===睡眠:" + 4 + "s");
} catch (InterruptedException e) {
e.printStackTrace();
}
return 99L;
}
@Override
public Long countCouponCountByUserId(Long userId) {
System.out.println("UserService获取CouponCount的线程 " + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(8);
System.out.println("获取CouponCount===睡眠:" + 8 + "s");
} catch (InterruptedException e) {
e.printStackTrace();
}
return 66L;
}
@Override
public List<String> countArticleCountByUserId(Long userId) {
List<String> list = new ArrayList<>();
System.out.println("UserService获取ArticleCount的线程 " + Thread.currentThread().getName());
try {
list.add("1");
list.add("2");
TimeUnit.SECONDS.sleep(8);
System.out.println("获取ArticleCount===睡眠:" + 8 + "s");
} catch (InterruptedException e) {
e.printStackTrace();
}
return list;
}
@Override
public Long countLikeCountByUserId(Long userId) {
System.out.println("UserService获取likeCount的线程 " + Thread.currentThread().getName());
try {
TimeUnit.SECONDS.sleep(8);
System.out.println("获取likeCount===睡眠:" + 8 + "s");
} catch (InterruptedException e) {
e.printStackTrace();
}
return 46L;
}
}