SpringBoot线程池的使用

第一步、配置线程池

package com.kyy.springboot.pool;

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

import java.util.concurrent.ThreadPoolExecutor;

/**
 * Auth: zhouhongliang
 * Date:2019/8/1
 */
@Configuration
public class GlobalConfig {
    @Bean
    public ThreadPoolTaskExecutor defaultThreadPool(){
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        //核心线程数量
        threadPoolTaskExecutor.setCorePoolSize(2);
        //最大线程数量
        threadPoolTaskExecutor.setMaxPoolSize(5);
        //队列中最大任务数
        threadPoolTaskExecutor.setQueueCapacity(2);
        //线程名称前缀
        threadPoolTaskExecutor.setThreadNamePrefix("ThreadPool-");
        //当达到最大线程数时如何处理新任务
        threadPoolTaskExecutor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //线程空闲后最大存活时间
        threadPoolTaskExecutor.setKeepAliveSeconds(60);
        //初始化线程池
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }
}

第二步、创建Service

package com.kyy.springboot.service;

import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.concurrent.ThreadPoolTaskExecutor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

/**
 * Auth: zhouhongliang
 * Date:2019/8/1
 */
@Service
public class BootService {
    @Resource(name = "defaultThreadPool")
    private ThreadPoolTaskExecutor poolTaskExecutor;

    @Async
    public void testPool() {
        System.out.println("线程名称:" + Thread.currentThread().getName());
    }

    public void testNoPool() {
        System.out.println("线程名称:" + Thread.currentThread().getName());
    }

    public int testPoolTaskExecutor(int n) throws InterruptedException, ExecutionException {
        CountDownLatch countDownLatch = new CountDownLatch(n);
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        int sum = 0;
        for (int i = 1; i <= n; i++) {
            final int index = i;
            final Future<Integer> future = poolTaskExecutor.submit(() -> {
                Thread.sleep(5000);
                System.out.println(simpleDateFormat.format(new Date())+" "+Thread.currentThread().getName() + " 执行 " + index);
                countDownLatch.countDown();
                return 1;
            });
        }
        countDownLatch.await();
        return sum;
    }
}

第三步:创建Controller

package com.kyy.springboot.controller;

import com.kyy.springboot.service.BootService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.concurrent.ExecutionException;

/**
 * Auth: zhouhongliang
 * Date:2019/8/1
 */
@RestController
public class PoolController {
    @Autowired
    private BootService bootService;
    @RequestMapping("/pool")
    public String pool(){
        for (int i=0;i<100;i++){
            bootService.testPool();
        }
        return "pool test";
    }
    @RequestMapping("/poolTask/{n}")
    public String poolTask(@PathVariable int n){
        long startTime = System.currentTimeMillis();
        try {
            bootService.testPoolTaskExecutor(n);
        } catch (InterruptedException e) {
            e.printStackTrace();
        } catch (ExecutionException e) {
            e.printStackTrace();
        }
        long endTime = System.currentTimeMillis();
        return "poolTask test "+(endTime-startTime)/1000+" 秒";
    }
}

第四步:创建启动类

package com.kyy.springboot;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.scheduling.annotation.EnableAsync;

/**
 * 启动程序
 * @Auther:zhouhongliang
 * @Date:2019/7/30
 * @Description:
 */
@SpringBootApplication
@EnableAsync
public class SpringBootDemo {
    public static void main(String[] args) {
        SpringApplication.run(SpringBootDemo.class,args);
    }
}

总结:线程池配置说明
1、属性字段说明

corePoolSize:线程池维护线程的最少数量

keepAliveSeconds:允许的空闲时间

maxPoolSize:线程池维护线程的最大数量

queueCapacity:缓存队列

rejectedExecutionHandler:对拒绝task的处理策略

2、 execute(Runable)方法执行过程
如果此时线程池中的数量小于corePoolSize,即使线程池中的线程都处于空闲状态,也要创建新的线程来处理被添加的任务。

如果此时线程池中的数量等于 corePoolSize,但是缓冲队列 workQueue未满,那么任务被放入缓冲队列。

如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量小于maxPoolSize,建新的线程来处理被添加的任务。

如果此时线程池中的数量大于corePoolSize,缓冲队列workQueue满,并且线程池中的数量等于maxPoolSize,那么通过handler所指定的策略来处理此任务。也就是:处理任务的优先级为:核心线程corePoolSize、任务队列workQueue、最大线程 maximumPoolSize,如果三者都满了,使用handler处理被拒绝的任务。

当线程池中的线程数量大于corePoolSize时,如果某线程空闲时间超过keepAliveTime,线程将被终止。这样,线程池可以动态的调整池中的线程数。

原文地址:https://blog.51cto.com/11147669/2425799

时间: 2024-10-08 10:43:52

SpringBoot线程池的使用的相关文章

springboot线程池的使用和扩展

我们常用ThreadPoolExecutor提供的线程池服务,springboot框架提供了@Async注解,帮助我们更方便的将业务逻辑提交到线程池中异步执行,今天我们就来实战体验这个线程池服务: 本文地址:http://blog.csdn.net/boling_cavalry/article/details/79120268 实战环境 windowns10: jdk1.8: springboot 1.5.9.RELEASE: 开发工具:IntelliJ IDEA: 实战源码 本次实战的源码可以

Springboot线程池服务实战分享

我们常用ThreadPoolExecutor提供的线程池服务,springboot框架提供了@Async注解,帮助我们更方便的将业务逻辑提交到线程池中异步执行,今天我们就来实战体验这个线程池服务:实战环境windowns10:jdk1.8:springboot 1.5.9.RELEASE:开发工具:IntelliJ IDEA: 这里面有多个工程,本次用到的工程为threadpooldemoserver,如下图红框所示:实战步骤梳理本次实战的步骤如下:创建springboot工程:创建Servic

SpringBoot开发案例之多任务并行+线程池处理

前言 前几篇文章着重介绍了后端服务数据库和多线程并行处理优化,并示例了改造前后的伪代码逻辑.当然了,优化是无止境的,前人栽树后人乘凉.作为我们开发者来说,既然站在了巨人的肩膀上,就要写出更加优化的程序. SpringBoot开发案例之JdbcTemplate批量操作 SpringBoot开发案例之CountDownLatch多任务并行处理 改造 理论上讲,线程越多程序可能更快,但是在实际使用中我们需要考虑到线程本身的创建以及销毁的资源消耗,以及保护操作系统本身的目的.我们通常需要将线程限制在一定

springboot中使用自定义线程池ThreadPoolTaskExecutor

java5以后,线程有了很大的变化,在使用上更加方便功能更佳强大,Springboot里面进行了进一步的封装. 我们来看一个例子 package com.executor; import java.util.concurrent.Executor;import java.util.concurrent.RejectedExecutionHandler;import java.util.concurrent.ThreadPoolExecutor; import org.springframewor

Springboot的异步线程池图鉴

1:定义线程池 @EnableAsync @Configuration class TaskPoolConfig { @Bean("taskExecutor") public Executor taskExecutor() { ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor(); executor.setCorePoolSize(10); executor.setMaxPoolSize(20); executor

如何使用加拿大28源码下载理解线程池

平时接触过加拿大28源码下载[dashengba.com]Q3266397597多线程开发的童鞋应该都或多或少了解过线程池,之前发布的<阿里巴巴 Java 手册>里也有一条:可见线程池的重要性.简单来说使用线程池有以下几个目的:线程是稀缺资源,不能频繁的创建.解耦作用:线程的创建于执行完全分开,方便维护.应当将其放入一个池子中,可以给其他任务进行复用.线程池原理谈到线程池就会想到池化技术,其中最核心的思想就是把宝贵的资源放到一个池子中:每次使用都从里面获取,用完之后又放回池子供其他人使用,有点

如何优雅的使用和理解线程池

前言 平时接触过多线程开发的童鞋应该都或多或少了解过线程池,之前发布的<阿里巴巴 Java 手册>里也有一条: 可见线程池的重要性. 简单来说使用线程池有以下几个目的: 线程是稀缺资源,不能频繁的创建. 解耦作用:线程的创建于执行完全分开,方便维护. 应当将其放入一个池子中,可以给其他任务进行复用. 线程池原理 谈到线程池就会想到池化技术,其中最核心的思想就是把宝贵的资源放到一个池子中:每次使用都从里面获取,用完之后又放回池子供其他人使用,有点吃大锅饭的意思. 那在 Java 中又是如何实现的

如何优雅的使用和理解线程池----转

线程池原理 谈到线程池就会想到池化技术,其中最核心的思想就是把宝贵的资源放到一个池子中:每次使用都从里面获取,用完之后又放回池子供其他人使用,有点吃大锅饭的意思. 那在 Java 中又是如何实现的呢? 在 JDK 1.5 之后推出了相关的 api,常见的创建线程池方式有以下几种: Executors.newCachedThreadPool():无限线程池. Executors.newFixedThreadPool(nThreads):创建固定大小的线程池. Executors.newSingle

Java 线程池ExecutorService运行原理 和FutureTask 的使用

一.线程池ExecutorService运行原理 ThreadPoolExecutor中有corePoolSize(核心线程)和maximumPoolSize(工作线程),默认核心线程和工作线程数量一致.1.当线ExecutorService线程池,使用submit,或者execute时2.先判断运行中的线程是否大于corePoolSize(核心线程)数量3.如果大于corePoolSize(核心线程)且maximumPoolSize(工作线程)未满则把该线程存着到工作线程等待.4.如果大于co