springboot多线程处理list并返回list结果

业务:

订单(id,用户id)---用户(id,用户名),要求返回订单且带用户名,视图(订单id,用户id,用户名)

目录结构:

 

 

 代码:

在Application中通过@EnableAsync开启springboot多线程支持

 

 

bean:

package com.example.demo.thread.bean;

import lombok.Data;

import java.time.LocalDateTime;

/**
 * 订单
 */
@Data
public class Order {
    private Long id;
    private Long userId;
    private LocalDateTime createTime;

}
package com.example.demo.thread.bean;

import lombok.Data;

/**
 * 返回结果:订单试图
 */
@Data
public class OrderVO extends Order{
    private String userName;
    
}
package com.example.demo.thread.bean;

import lombok.Data;

/**
 * 用户
 */
@Data
public class User {
    private Long id;
    private String userName;


}

config配置:

package com.example.demo.thread.config;

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 {

    //获取cpu线程数+1
    private static final int threadNum = Runtime.getRuntime().availableProcessors() + 1;

    // 核心线程池大小
    public static int corePoolSize = threadNum;

    //最大线程数
    private int maxPoolSize = 2 * threadNum;

    //线程池维护线程所允许的空闲时间 1分钟
    private int keepAliveSeconds = 60;

    //队列最大长度
    private int queueCapacity = 1024;

    //线程池名前缀
    private static final String threadNamePrefixName = "Async-Test-Service-";

    /**
     * 自定义线程池
     * @return
     */
    @Bean(name = "threadPoolTaskExecutor")
    public ThreadPoolTaskExecutor createThreadPoolTaskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //最大线程数
        executor.setMaxPoolSize(maxPoolSize);
        //核心线程数
        executor.setCorePoolSize(threadNum);
        //线程活跃时间(秒)
        executor.setKeepAliveSeconds(keepAliveSeconds);
        //默认线程名称
        executor.setThreadNamePrefix(threadNamePrefixName);
        //阻塞队列容量
        executor.setQueueCapacity(queueCapacity);
        //设置拒绝策略:不在新线程中执行任务,而是由调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        // 等待所有任务结束后再关闭线程池
        executor.setWaitForTasksToCompleteOnShutdown(true);
        //初始化
        executor.initialize();
        return executor;
    }


}

service:

package com.example.demo.thread.service;

import com.example.demo.thread.bean.OrderVO;
import com.example.demo.thread.bean.User;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;

import java.util.List;
import java.util.concurrent.Future;

@Service
public class OrderService {


    @Async(value = "threadPoolTaskExecutor")
    public Future<List<OrderVO>> getData(List<OrderVO> orderVOS, List<User> users) {
        System.out.println("多线程名: " + Thread.currentThread().getName());
        try {
            //模拟从数据库里查数据
            Thread.sleep(10);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        //处理数据
        orderVOS.stream().forEach(item -> {
            users.stream().forEach(user -> {
                if (item.getUserId().equals(user.getId())) {
                    item.setUserName(user.getUserName());
                }
            });
        });
        //返回对象
        Future<List<OrderVO>> result = new AsyncResult<>(orderVOS);
        return result;
    }

    //单线程
    public List<OrderVO> getData1(List<OrderVO> orderVOS, List<User> users) {
        System.out.println("单线程名: " + Thread.currentThread().getName());
        //处理数据
        orderVOS.stream().forEach(item -> {
            try {
                //模拟从数据库里查数据
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            users.stream().forEach(user -> {
                if (item.getUserId().equals(user.getId())) {
                    item.setUserName(user.getUserName());
                }
            });
        });
        return orderVOS;
    }

}

controller:

package com.example.demo.thread.controller;

import com.example.demo.thread.bean.OrderVO;
import com.example.demo.thread.bean.User;
import com.example.demo.thread.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PostConstruct;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.concurrent.Future;
import java.util.stream.Collectors;

@RestController
@RequestMapping("/order")
public class OrderController {

    private List<OrderVO> orderVOS = new ArrayList<>();
    private List<User> users = new ArrayList<>();


    @Autowired
    private OrderService orderService;


    /**
     * 初始化数据
     */
    @PostConstruct
    public void createData() {
        //数据量
        long dataCount = 10;
        // 创建订单数据。模拟已经插入到数据库的订单
        for (long i = 0; i < dataCount; i++) {
            OrderVO orderVO = new OrderVO();
            orderVO.setId(i + 1);
            orderVO.setUserId(i + 1);
            //防止电脑太快,导致都是同一个时间,所以加一个数
            orderVO.setCreateTime(LocalDateTime.now().plusSeconds(i));
            orderVOS.add(orderVO);
        }

        // 创建用户数据。模拟已经插入到数据库的用户
        for (long i = 0; i < dataCount; i++) {
            User user = new User();
            user.setId(i + 1);
            user.setUserName("用户名" + (i + 1));
            users.add(user);
        }
        orderVOS = orderVOS.stream()
                .sorted(Comparator.comparing(OrderVO::getCreateTime).reversed())
                .collect(Collectors.toList());
    }


    /**
     * 单线程
     * @return
     */
    @GetMapping("/getSingletonOrderDetails")
    public List<OrderVO> getOrderDetails1() {
        long startTime = System.currentTimeMillis();
        //这里是不同的执行方式(单线程/线程池)
        List<OrderVO> result = orderService.getData1(orderVOS, users);
        long endTime = System.currentTimeMillis();
        System.out.println("数据量:"+result.size()+",单线程:执行时间:" + (endTime - startTime) + " ms");
        return result;
    }



    /**
     * 多线程
     * @return
     */
    @GetMapping("/getMultOrderDetails")
    public List<OrderVO> getOrderDetails() {
        long startTime = System.currentTimeMillis();

        //这里是不同的执行方式(单线程/线程池)
        Future<List<OrderVO>> future = orderService.getData(orderVOS, users);
        //返回结果
        List<OrderVO> orderVOList = new ArrayList<>();
        try {
            orderVOList = future.get();
        } catch (Exception e) {
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        System.out.println("数据量:"+orderVOList.size()+",多线程:执行时间:" + (endTime - startTime) + " ms");
        return orderVOList;
    }









}

测试:

单线程:http://192.168.0.30:8081/order/getSingletonOrderDetails

多线程:http://192.168.0.30:8081/order/getMultOrderDetails

结果:

 

 

 

 备注:这里调整数据量的大小

 

posted on 2022-09-23 11:20  栖梧  阅读(3018)  评论(0编辑  收藏  举报