JAVA SpringBoot 项目 多线程、线程池的使用。

1.1  线程:
线程就是进程中的单个顺序控制流,也可以理解成是一条执行路径

单线程:一个进程中包含一个顺序控制流(一条执行路径)

多线程:一个进程中包含多个顺序控制流(多条执行路径)

在java语言中:
 线程A和线程B,堆内存和方法区内存共享。
 但是栈内存独立,一个线程一个栈。

假设启动10个线程,会有10个栈空间,每个栈和每个栈之间,互不干扰,各自执行各自的,这就是多线程并发。

java中之所以有多线程机制,目的就是为了提高程序的处理效率。

对于单核的CPU来说,不能够做到真正的多线程并发,但是可以做到给人一种“多线程并发”的感觉。对于单核的CPU来说,在某一个时间点上实际上只能处理一件事情,但是由于CPU的处理速度极快,多个线程之间频繁切换执行,跟人来的感觉是多个事情同时在做。

 1.2 线程的生命周期

1.3 线程池

        线程池可以看做是线程的集合。它的工作主要是控制运行的线程的数量,处理过程中将任务放入队列,然后在线程创建后 启动这些任务,如果线程数量超过了最大数量超出数量的线程排队等候,等其它线程执行完毕, 再从队列中取出任务来执行。他的主要特点为:线程复用;控制最大并发数;管理线程。

1.4 为什么使用线程池

        使用线程池最大的原因就是可以根据系统的需求和硬件环境灵活的控制线程的数量,且可以对所有的线程进行统一的管理和控制,从而提高系统的运行效率降低系统运行压力;当然了,使用线程池的原因不仅仅只有这些,我们可以从线程池自身的优点上来进一步了解线程池的好处。(1)线程和任务分离,提升线程的重用性。

(2)控制线程的并发数量,降低服务器压力,统一管理所有的线程。

(3)提升系统的响应速度,假如创建线程用的时间为T1,执行任务用的时间为T2,销毁线程用的时间为T3,那么使用线程就免去了T1和T3的时间。

1.5 线程池的应用场景

(1)商品秒杀
(2)云盘文件上传下载
(3)12306 网上购票系统

总之,只要是有并发的地方、任务量大或者小、每个任务执行时间长或短的都可以使用线程池,只不过在使用线程池的时候,注意下设置合理的线程池大小即可;

2.1 实现方式 (springboot实现多线程)

1. 自定义线程池配置,我自己的项目在没有充分的把握情况下一般不修改手脚架的配置,避免出现不明原因。加上我们经理之前也教我,能不修改别人的代码,尽量不修改别人的代码,因为你不确定别人是如何调用的。


/**
 * xxx业务专用的线程池配置类
 */
@Configuration
public class TalentIotThreadConfig  {


    /**
     * ThreadPoolTaskExecutor的处理流程
     * 当池子大小小于corePoolSize,就新建线程,并处理请求
     * 当池子大小等于corePoolSize,把请求放入workQueue中,池子里的空闲线程就去workQueue中取任务并处理
     * 当workQueue放不下任务时,就新建线程放入线程池,并处理请求,如果池子大小撑到了maximumPoolSize,就用RejectedExecutionHandler来做拒绝处理
     * 当池子的线程数大于corePoolSize时,多余的线程会等待keepAliveTime长时间,如果无请求可处理就自行销毁
     *
     * @return
     */

    @Bean("TalentIotThread")
    public ThreadPoolTaskExecutor  getAsyncExecutor() {
        ThreadPoolTaskExecutor tp = new ThreadPoolTaskExecutor();
        //设置核心线程数
        tp.setCorePoolSize(10);
        //设置最大线程数
        tp.setMaxPoolSize(100);
        //线程使用的缓冲队列
        tp.setQueueCapacity(10);
        //设置程序关闭时要等待线程全部执行完
        tp.setWaitForTasksToCompleteOnShutdown(true);
        //设置等待时间,超过等待时间后立即停止
        tp.setAwaitTerminationSeconds(60);
        //线程名称前缀
        tp.setThreadNamePrefix("talent-iot-task-");
        //初始化线程
        tp.initialize();
        // 设置拒绝策略
        // rejection-policy:当pool已经达到max size的时候,如何处理新任务
        // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
        tp.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        return tp;
    }

}

2. 调用,ThreadPoolExecutor它的顶级父类是Executor接口,只包含了一个方法——execute,这个方法也就是线程池的“执行”。

注意:ThreadPoolTaskExecutor.execute方法不会立即执行,而是将任务放入线程池中,等待线程池中的线程去执行。


public class IotTimer {
  //通过注解引入配置
    @Resource(name = "TalentIotThread")
    private Executor executor;

    @Scheduled(cron = "0 */2 * * * ?")
    void talIotDataShare() {
        for (TalIotDateShare iotDateShare : shareList) {

             executor.execute(() -> {
                   // 业务代码                 

                 });

           }

    }

}

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值