Java线程池的使用(简单实现)

一、线程池的概念

创建Java线程需要给线程分配堆栈内存以及初始化内存,还需要进行系统调用,频繁地创建和销毁线程会大大降低系统的运行效率,采用线程池来管理线程有以下好处:

  1. 提升性能:线程池能独立负责线程的创建、维护和分配
  2. 线程管理:每个Java线程池会保持一些基本的线程统计信息,对线程进行有效管理

二、线程池的应用场景

传输文件

签到和秒杀

爬虫

三、线程池的基本使用

controller层

package tech.niua.admin.multithreading.controller;

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 tech.niua.admin.multithreading.service.ThreadService;

import java.util.List;

@RestController
@RequestMapping("/thread")
public class MultiThreadController {

    @Autowired
    private ThreadService threadService;

    @GetMapping("/testThreadData")
    public List testThreadData(){
        System.out.println(threadService.getAllResult()+"线程返回数据");
        return threadService.getAllResult();
    }
}

 service层(这里在service层写了一个方法的封装,当然也可以在service写业务)

package tech.niua.admin.multithreading.service.impl;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tech.niua.admin.multithreading.MultiThreadQueryUtil;
import tech.niua.admin.multithreading.service.ThreadService;

import java.util.List;

@Service
public class ThreadServiceImpl implements ThreadService {

    @Autowired
    private MultiThreadQueryUtil multiThreadQueryUtil;



    @Override
    public List getAllResult() {
        return multiThreadQueryUtil.getMultiCombineResult();
    }
}

MultiThreadQueryUtil类

我这里的数据一共11条

package tech.niua.admin.multithreading;


import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import tech.niua.admin.multithreading.mapper.WorkflowTaskMapper;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;

@Service
public class MultiThreadQueryUtil {

    @Autowired
    private WorkflowTaskMapper workflowTaskMapper;

    /**
     * 获取多线程结果并进行结果合并
     * @return
     */
    public List<List> getMultiCombineResult() {
        //开始时间
        long start = System.currentTimeMillis();
        //返回结果
        List<List> result = new ArrayList<>();
        //查询数据库总数量
        int count = workflowTaskMapper.selectCountAll();
        //这里对数据库中的数据进行了一个分组,每组交给不同的线程,每5个为一组
        //当然这里的逻辑都可以根据自己相应的业务进行更改
        Map<String,String> splitMap = ExcelLocalUtils.getSplitMap(count,5);

        //Callable用于产生结果
        List<Callable<List>> tasks = new ArrayList<>();
        for (int i = 1; i <= 3; i++) {
            //不同的线程用户处理不同分段的数据量,这样就达到了平均分摊查询数据的压力
            System.out.println(splitMap.get(String.valueOf(i)));
            String[] nums = splitMap.get(String.valueOf(i)).split(":");
            int startNum = Integer.valueOf(nums[0]);
            int endNum = Integer.valueOf(nums[1]);
            //将相应的任务放到Callable
            Callable<List> qfe = new ThreadQuery(startNum, endNum-startNum+1);
            tasks.add(qfe);
        }
        try{
            //定义固定长度的线程池  防止线程过多,5就够用了
            ExecutorService executorService = Executors.newFixedThreadPool(5);
            //Future用于一并获取结果
            List<Future<List>> futures=executorService.invokeAll(tasks);
            //处理线程返回结果
            if(futures!=null&&futures.size() > 0){
                for (Future<List> future:futures){
                    result.addAll(future.get());
                }
            }
            //关闭线程池,一定不能忘记
            executorService.shutdown();
        }catch (Exception e){
            e.printStackTrace();
        }
        long end = System.currentTimeMillis();
        System.out.println("线程查询数据用时:"+(end-start)+"ms");
        return result;
    }

}

 ThreadQuery 类

package tech.niua.admin.multithreading;

import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Callable;

public class ThreadQuery implements Callable<List> {

//    public static SpringContextUtil springContextUtil = new SpringContextUtil();

    private int start;

    private int end;

    //每个线程查询出来的数据集合
    private List datas;

    public  ThreadQuery(int start,int end) {
       //这里可以实现相应的业务代码
    }

    //返回数据给Future
    @Override
    public List call() throws Exception {
        return datas;
    }

}

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值