java spring Boot 多线程实例

1,先添加线程池的公共配置类

package com.sport.sportactivityserver.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;


@Configuration
public class ApplicationConfiguration {
    
    

    /**
     * 公共线程池
     */
    @Bean
    public ThreadPoolTaskExecutor commonThreadPoolTaskExecutor() {
    
    
        ThreadPoolTaskExecutor pool = new org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor();
        int processNum = Runtime.getRuntime().availableProcessors(); // 返回可用处理器的Java虚拟机的数量
        int corePoolSize = (int) (processNum / (1 - 0.2));
        int maxPoolSize = (int) (processNum / (1 - 0.5));
        pool.setCorePoolSize(corePoolSize); // 核心池大小
        pool.setMaxPoolSize(maxPoolSize); // 最大线程数
        pool.setQueueCapacity(maxPoolSize * 1000); // 队列程度
        pool.setThreadPriority(Thread.MAX_PRIORITY);
        pool.setDaemon(false);
        pool.setKeepAliveSeconds(300);// 线程空闲时间
        return pool;
    }
}

2,使用线程池

package com.sport.sportactivityserver.controller.lottery;

import com.google.common.collect.Lists;
import com.sport.sportactivityserver.vo.ResultData;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import java.util.List;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorCompletionService;

/**
 * @Description:
 * @Author: zdj
 * @Date: 2021/11/23
 * @version: 1.0.0
 */
@RestController
@RequestMapping("/thread-use")
@Api(tags = "线程池应用")
public class LyUserController {
    
    
    /**
     * 注入线程池对象
     */
    @Qualifier("commonThreadPoolTaskExecutor")
    @Autowired
    private ThreadPoolTaskExecutor threadPoolTaskExecutor;

    @ApiOperation(value = "多线程--跑任务", notes = "多线程--跑任务", httpMethod = "POST")
    @RequestMapping(value = "/textMoreThred", method = RequestMethod.POST)
    public ResultData<Object> textMoreThred(){
    
    
        // 开始时间
        Long startTime = System.currentTimeMillis();

        List<Integer> result = Lists.newArrayList();
        for (int i = 1; i <= 3000000; i++) {
    
    
            result.add(i);
        }
        System.out.println("多线程处理前结果:"+result);

        /**
         * partition()方法 大家可以看一下
         * 例如 3001条数据 他会自动帮你分成两个数组 第一个数组3000条 第二个数组1条
         * 不需要我们再像以前一样 通过for循环处理截取
         */
        // 注入线程池
        ExecutorCompletionService<Integer> completionService = new ExecutorCompletionService<Integer>(threadPoolTaskExecutor);
        List<List<Integer>> lists = Lists.partition(result, 300000);
        lists.forEach(item -> {
    
    
            // 这里做的事情就是 根据lists大小确认要多少个线程 给每个线程【分配】任务
            completionService.submit(new Callable() {
    
    
                @Override
                public Object call() throws Exception {
    
    
                    for (int i = 0,len = item.size(); i < len; i++) {
    
    
                        item.set(i, item.get(i) + 1);
                    }
                    return true;
                }
            });
        });

        // 这里是让多线程开始执行
        lists.forEach(item -> {
    
    
            try {
    
    
                completionService.take().get();
            } catch (InterruptedException | ExecutionException e) {
    
    
                System.out.println(e);
            }
        });
        System.out.println("多线程处理后结果:"+result);

        // 放在要检测的代码段前,取结束后的时间戳
        Long endTime = System.currentTimeMillis();

        return ResultData.error("多线程花费时间:"+this.getExpendTime((endTime - startTime)));
    }

    @ApiOperation(value = "单个线程--跑任务", notes = "单个线程--跑任务", httpMethod = "POST")
    @RequestMapping(value = "/textOneThred", method = RequestMethod.POST)
    public ResultData<Object> textOneThred(){
    
    
        // 开始时间
        Long startTime = System.currentTimeMillis();
        List<Integer> result = Lists.newArrayList();
        for (int i = 1; i <= 3000000; i++) {
    
    
            result.add(i);
        }
        System.out.println("单线程处理前结果:"+result);


        for (int i = 0,len = result.size(); i < len; i++) {
    
    
            result.set(i, result.get(i) + 1);
        }
        System.out.println("单线程处理后结果:"+result);

        // 结束时间
        Long endTime = System.currentTimeMillis();

        return ResultData.error("单线程花费时间:" + this.getExpendTime((endTime - startTime)));
    }

    /**
     * 需要转化的时间
     * @param tempTime
     * @return
     */
    private String getExpendTime(Long tempTime){
    
    
        return  (((tempTime / 86400000) > 0) ? ((tempTime / 86400000) + "d") : "") +
                ((((tempTime / 86400000) > 0) || ((tempTime % 86400000 / 3600000) > 0)) ? ((tempTime % 86400000 / 3600000) + "h") : ("")) +
                ((((tempTime / 3600000) > 0) || ((tempTime % 3600000 / 60000) > 0)) ? ((tempTime % 3600000 / 60000) + "m") : ("")) +
                ((((tempTime / 60000) > 0) || ((tempTime % 60000 / 1000) > 0)) ? ((tempTime % 60000 / 1000) + "s") : ("")) +
                ((tempTime % 1000) + "ms");
    }
}

3,结果对比
在这里插入图片描述
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/gelinwangzi_juge/article/details/122671408