线程池与异步编程——语法归纳

一、Java 原生线程池(java.util.concurrent

1.1 创建线程池(推荐使用 ThreadPoolExecutor

ThreadPoolExecutor executor = new ThreadPoolExecutor(
    5,                     // 核心线程数 corePoolSize
    10,                    // 最大线程数 maximumPoolSize
    60L,                   // 空闲线程存活时间 keepAliveTime
    TimeUnit.SECONDS,      // 时间单位
    new LinkedBlockingQueue<>(100),  // 队列(有界队列防止 OOM)
    Executors.defaultThreadFactory(), // 线程工厂
    new ThreadPoolExecutor.AbortPolicy() // 拒绝策略
);

如果 线程数已经达到最大值,并且 队列也满了,线程池就没有能力再接新任务了。

这时必须要做一个选择 —— 这就是 拒绝策略

📌 常见 拒绝策略

  • AbortPolicy:抛异常(默认)。
  • CallerRunsPolicy:由调用者线程执行任务。
  • DiscardPolicy:直接丢弃任务。
  • DiscardOldestPolicy:丢弃最旧任务,执行当前任务。

1.2 使用线程池

executor.execute(() -> System.out.println("执行任务1"));

Future<String> future = executor.submit(() -> "任务结果");
System.out.println(future.get());  // 阻塞等待结果

executor.shutdown();  // 关闭线程池

1.3 Executors 工厂方法(不推荐生产使用)

Executors.newFixedThreadPool(5);   // 固定大小线程池
Executors.newCachedThreadPool();   // 缓存线程池,按需创建
Executors.newSingleThreadExecutor(); // 单线程
Executors.newScheduledThreadPool(5); // 定时/周期任务

👉 问题:这些方法的队列可能是 无界的,容易导致 OOM,所以阿里规范建议直接用 ThreadPoolExecutor

二、Spring 线程池(推荐在企业项目中用)

Spring 对线程池做了封装,常用 ThreadPoolTaskExecutor(基于 Java ThreadPoolExecutor)。


2.1 配置线程池(Java Config 方式)

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

import java.util.concurrent.Executor;

@Configuration
public class ThreadPoolConfig {

    @Bean("myExecutor")
    public Executor taskExecutor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(5);       // 核心线程数
        executor.setMaxPoolSize(10);       // 最大线程数
        executor.setQueueCapacity(100);    // 队列容量
        executor.setKeepAliveSeconds(60);  // 空闲线程存活时间
        executor.setThreadNamePrefix("my-thread-"); // 线程名前缀
        executor.setRejectedExecutionHandler(new java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy());
        executor.initialize(); // 初始化
        return executor;
    }
}

2.2 使用线程池

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;

@Service
public class MyService {

    @Async("myExecutor")  // 指定使用哪个线程池
    public void asyncTask() {
        System.out.println("执行异步任务:" + Thread.currentThread().getName());
    }
}

⚡ 记得在启动类开启异步支持:

@EnableAsync
@SpringBootApplication
public class MyApplication { }

2.3 Spring Boot 配置文件方式(更简洁)

application.yml

spring:
  task:
    execution:
      pool:
        core-size: 5
        max-size: 10
        queue-capacity: 100
        keep-alive: 60s
      thread-name-prefix: my-thread-

使用时同样写 @Async 注解即可。

三、异步编程

CompletableFuture 是Futrue 的增强版,不阻塞线程,一般搭配线程池使用,执行异步任务。

Future 工作流程

主线程 ── submit(task) ──► 线程池执行task
主线程 ── get() ──(阻塞等待)────────────┐
                                     │ 任务完成/异常
主线程 ◄────────────── 返回结果/抛异常 ─┘

CompletableFuture 工作流程

主线程 ── supplyAsync(task) ─► 线程池执行task
主线程 ── thenApply(...) / thenAccept(...)/whenComplete(...)   // 只是注册回调,立刻返回

(稍后某时)
线程池工作线程:task完成 → 将“完成信号”分派给已注册的回调

异步执行任务,无线程

// thenApply: 有入参有返回(T -> R)
CompletableFuture<Integer> cf =
    CompletableFuture.supplyAsync(() -> 21)
        .thenApply(x -> x * 2); // -> 42

指定线程池


// 指定线程池
ExecutorService pool = Executors.newFixedThreadPool(8);
CompletableFuture<String> f3 = CompletableFuture.supplyAsync(() -> "hi", pool);
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值