java线程池实战应用步骤详解

 更新时间:2025年04月02日 12:07:08   作者:时间_wys  
这篇文章主要介绍了java线程池实战应用小结,包括线程池的创建方式,本文给大家分享两种方式,结合实例代码给大家介绍的非常详细,需要的朋友参考下吧

一、线程池的创建方式

方式(一):通过构造函数ThreadPoolExecutor()方式创建线程池

步骤1:先构建线程池

public class AsyncTaskExecutor {
    /**
     * 核心线程数
     */
    private static final int corePoolSize = 10;
    /**
     * 最大线程数
     */
    private static final int maxPoolSize = 30;
    /**
     * 空闲线程回收时间
     * 空闲线程是指:当前线程池中超过了核心线程数之后,多余的空闲线程的数量
     */
    private static final int keepAliveTime = 100;
    /**
     * 任务队列/阻塞队列
     */
    private static final int blockingQueueSize = 99999;
    private static final ThreadPoolExecutor executorPool = new ThreadPoolExecutor(
            corePoolSize,
            maxPoolSize,
            keepAliveTime,
            TimeUnit.MILLISECONDS,
            new LinkedBlockingQueue<>(blockingQueueSize),
            new ThreadFactoryBuilder().setNameFormat("AsyncTaskThread" + "-%d").build(),
            new ThreadPoolExecutor.CallerRunsPolicy()
    );
    /**
     * 异步任务执行
     *
     * @param task
     */
    public static void execute(Runnable task) {
        executorPool.execute(task);
    }
}

步骤2:通过实现Runnable接口,创建异步任务

@Slf4j
public class CommonTask implements Runnable {
    /**
     * 模块ID
     */
    private Long modelId;
    /**
     * 模块名称
     */
    private ModelEnum modelName;
    /**
     * 构造方法
     *
     * @param modelId
     * @param modelName
     */
    public CommonTask(Long modelId, ModelEnum modelName) {
        this.modelId = modelId;
        this.modelName = modelName;
    }
    @Override
    public void run() {
        log.info("start to process common task!!!");
        if (modelId.intValue() == ModelEnum.Chinese.getCode()) {
            String name = ModelEnum.Chinese.getValue();
            log.info("modelID = {}  modelName = {}", modelId, name);
        } else {
            modelName = ModelEnum.forValue(modelId.intValue());
            log.info("modelID = {}  modelName = {}", modelId, modelName.getValue());
        }
    }
}

枚举

public enum ModelEnum {
    Chinese(1, "语文"),
    Math(2, "数学"),
    English(3, "数学");
    /**
     * code
     */
    private int code;
    /**
     * value
     */
    private String value;
    /**
     * 映射结果集
     */
    private static final Map<Integer, ModelEnum> VALUE_MAP;
    static {
        VALUE_MAP = new HashMap<>();
        for (ModelEnum modelEnum : ModelEnum.values()) {
            VALUE_MAP.put(modelEnum.code, modelEnum);
        }
    }
    ModelEnum(int code, String value) {
        this.code = code;
        this.value = value;
    }
    public int getCode() {
        return code;
    }
    public String getValue() {
        return value;
    }
    /**
     * 根据code获取枚举实例
     *
     * @param code
     * @return
     */
    public static ModelEnum forValue(int code) {
        return VALUE_MAP.get(code);
    }
}

步骤3:验证

            //步骤1:创建异步任务
            CommonTask task = new CommonTask(1L, ModelEnum.Chinese);
            //步骤2:调用线程池异步执行任务
            AsyncTaskExecutor.execute(task);
            log.info("main thread over...");

结果如下:

2024-05-23 14:53:16.096  INFO 20652 --- [           main] com.example.demo.dao.UserDaoTest         : main thread over...
2024-05-23 14:53:16.097  INFO 20652 --- [yncTaskThread-0] com.example.demo.task.CommonTask         : start to process common task!!!
2024-05-23 14:53:16.097  INFO 20652 --- [yncTaskThread-0] com.example.demo.task.CommonTask         : modelID = 1  modelName = 语文

方式(二):构建ThreadPoolTaskExecutor线程池,将其声明为Bean,可以通过注入bean的方式和在方法上使用@Async(“asyncTaskExecutor”)这种注解方式使用此线程池

@Slf4j
@Configuration
@EnableAsync
public class TaskExecutor {
    @Value("${async.executor.thread.core_pool_size}")
    private int corePoolSize;
    @Value("${async.executor.thread.max_pool_size}")
    private int maxPoolSize;
    @Value("${async.executor.thread.queue_capacity}")
    private int queueCapacity;
    @Value("${async.executor.thread.name.deal_task}")
    private String taskNamePrefix;
    /**
     * 构建线程池 并将其声明为Bean
     * 方式1:可以通过注入的方式使用此线程池
     * 方式2:可以在方法上使用@Async("asyncTaskExecutor")这种注解方式使用此线程池
     *
     * @return
     */
    @Bean(name = "asyncTaskExecutor")
    public Executor asyncTaskExecutor() {
        log.info("start asyncTaskExecutor...");
        ThreadPoolTaskExecutor threadPoolTaskExecutor = new ThreadPoolTaskExecutor();
        threadPoolTaskExecutor.setCorePoolSize(corePoolSize);
        threadPoolTaskExecutor.setMaxPoolSize(maxPoolSize);
        threadPoolTaskExecutor.setQueueCapacity(queueCapacity);
        threadPoolTaskExecutor.setThreadNamePrefix(taskNamePrefix);
        //拒绝策略:当前线程数已经达到最大线程数后,如何处理新任务
        //CallerRunsPolicy()不在新线程中执行任务,而是返回调用者所在的线程来执行
        threadPoolTaskExecutor.setRejectedExecutionHandler(
                new ThreadPoolExecutor.CallerRunsPolicy());
        threadPoolTaskExecutor.initialize();
        return threadPoolTaskExecutor;
    }
}

在application.yml中的配置

async:
  executor:
    thread:
      core_pool_size: 10
      max_pool_size: 10
      queue_capacity: 99999
      name:
        deal_task: DEAL-TASK-

使用方式1:在方法上使用@Async(“asyncTaskExecutor”)这种注解方式使用此线程池
使用方式2:通过注入的方式使用此线程池

@Slf4j
@Service
public class WorkServiceImpl implements WorkService {
    @Async("asyncTaskExecutor")
    public void doAsyncTask() throws InterruptedException {
        Thread.sleep(1000);
        log.info("do AsyncTask...");
    }
}
@Slf4j
@RunWith(SpringRunner.class)
@SpringBootTest
public class UserDaoTest {
    SqlSession sqlSession;
    @Resource
    private WorkService workService;
    @Resource
    private Executor asyncTaskExecutor;
    @Test
    public void test() {
        try {
            //方式1:在方法上使用@Async("asyncTaskExecutor")这种注解方式使用此线程池
            for (int i = 0; i < 5; i++) {
                workService.doAsyncTask();
            }
            log.info("main Thread over...");
            //方式2:通过注入的方式使用此线程池(方便)
            asyncTaskExecutor.execute(() -> {
                log.info("async task is running..");
            });
            Thread.sleep(5000);
        }catch (Exception e) {
            e.printStackTrace();
        }
    }
}

到此这篇关于java线程池实战应用总结的文章就介绍到这了,更多相关java线程池内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • MyBatis limit分页设置的实现

    MyBatis limit分页设置的实现

    这篇文章主要介绍了MyBatis limit分页设置的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2021-04-04
  • 使用Java实现创建Excel表单控件

    使用Java实现创建Excel表单控件

    在数据填报时,创建Excel表单控件是一项常见的任务,它可以极大地简化数据收集和处理的过程,本文主要介绍了如何使用Java实现创建Excel表单控件,感兴趣的可以了解下
    2024-03-03
  • Java使用itextpdf实现表单导出为pdf

    Java使用itextpdf实现表单导出为pdf

    这篇文章主要为大家详细介绍了Java如何使用itextpdf实现form表单导出为pdf,文中的示例代码讲解详细,感兴趣的小伙伴可以跟随小编一起学习一下
    2025-06-06
  • Spring的@RequestParam对象绑定方式

    Spring的@RequestParam对象绑定方式

    这篇文章主要介绍了Spring的@RequestParam对象绑定方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2021-10-10
  • Java编程实现beta分布的采样或抽样实例代码

    Java编程实现beta分布的采样或抽样实例代码

    这篇文章主要介绍了Java编程实现beta分布的采样或抽样实例,分享了相关代码示例,小编觉得还是挺不错的,具有一定借鉴价值,需要的朋友可以参考下
    2018-01-01
  • Spring使用hutool的HttpRequest发送请求的几种方式

    Spring使用hutool的HttpRequest发送请求的几种方式

    Spring HttpRequest是指Spring框架中的一个对象,它代表了HTTP客户端发送给Web服务器的一次请求,本文给大家介绍了Spring使用hutool的HttpRequest发送请求的几种方式,并通过代码示例讲解的非常详细,需要的朋友可以参考下
    2024-11-11
  • Java 多线程实例详解(三)

    Java 多线程实例详解(三)

    本文主要介绍 java 线程安全的知识,这里整理了相关资料及实现示例代码,有兴趣的小伙伴可以参考下
    2016-09-09
  • Java设计模式笔记之抽象工厂代码示例

    Java设计模式笔记之抽象工厂代码示例

    这篇文章主要介绍了Java设计模式笔记之抽象工厂代码示例,见解独到,代码详细,具有一定参考价值,需要的朋友可以了解下。
    2017-10-10
  • Java class文件格式总结_动力节点Java学院整理

    Java class文件格式总结_动力节点Java学院整理

    这篇文章主要介绍了Java class文件格式总结的相关资料,非常不错,具有参考借鉴价值,需要的的朋友参考下吧
    2017-06-06
  • Java中的List集合初始化及常见方法解析

    Java中的List集合初始化及常见方法解析

    这篇文章主要介绍了Java中的List集合初始化及常见方法解析,List集合的特点是元素有序可重复,只要是带集合、数组的都叫有序,因若无序就不会存在有下标,本文来讲一下List集合初始化及常见方法,需要的朋友可以参考下
    2023-10-10

最新评论