基于线程池和CompletableFuture实现抽奖系统10连抽

一:配置文件

java 复制代码
# 线程池配置
thread:
  pool:
    executor:
      config:
        core-pool-size: 20
        max-pool-size: 50
        keep-alive-time: 5000
        block-queue-size: 5000
        policy: CallerRunsPolicy

二 config:

java 复制代码
@Data
@ConfigurationProperties(prefix = "thread.pool.executor.config", ignoreInvalidFields = true)
public class ThreadPoolConfigProperties {

    /** 核心线程数 */
    private Integer corePoolSize = 20;
    /** 最大线程数 */
    private Integer maxPoolSize = 200;
    /** 最大等待时间 */
    private Long keepAliveTime = 10L;
    /** 最大队列数 */
    private Integer blockQueueSize = 5000;
    /*
     * AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
     * DiscardPolicy:直接丢弃任务,但是不会抛出异常
     * DiscardOldestPolicy:将最早进入队列的任务删除,之后再尝试加入队列的任务被拒绝
     * CallerRunsPolicy:如果任务添加线程池失败,那么主线程自己执行该任务
     * */
    private String policy = "AbortPolicy";

}
java 复制代码
@Slf4j
@EnableAsync
@Configuration
@EnableConfigurationProperties(ThreadPoolConfigProperties.class)
public class ThreadPoolConfig {

    @Bean
    @ConditionalOnMissingBean(ThreadPoolExecutor.class)
    public ThreadPoolExecutor threadPoolExecutor(ThreadPoolConfigProperties properties) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        // 实例化策略
        RejectedExecutionHandler handler;
        switch (properties.getPolicy()){
            case "AbortPolicy":
                handler = new ThreadPoolExecutor.AbortPolicy();
                break;
            case "DiscardPolicy":
                handler = new ThreadPoolExecutor.DiscardPolicy();
                break;
            case "DiscardOldestPolicy":
                handler = new ThreadPoolExecutor.DiscardOldestPolicy();
                break;
            case "CallerRunsPolicy":
                handler = new ThreadPoolExecutor.CallerRunsPolicy();
                break;
            default:
                handler = new ThreadPoolExecutor.AbortPolicy();
                break;
        }
        // 创建线程池
        return new ThreadPoolExecutor(properties.getCorePoolSize(),
                properties.getMaxPoolSize(),
                properties.getKeepAliveTime(),
                TimeUnit.SECONDS,
                new LinkedBlockingQueue<>(properties.getBlockQueueSize()),
                Executors.defaultThreadFactory(),
                handler);
    }

}

三: 定义抽奖逻辑

java 复制代码
import java.util.List;
import java.util.concurrent.ThreadLocalRandom;

public class LotterySystem {

    // 模拟抽奖逻辑,返回一个随机奖品
    public static String drawLottery() {
        // 模拟抽奖过程,假设奖品列表
        List<String> prizes = List.of("一等奖", "二等奖", "三等奖", "谢谢参与");
        int index = ThreadLocalRandom.current().nextInt(prizes.size());
        return prizes.get(index);
    }
}

四: 逻辑

java 复制代码
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.stream.Collectors;

public class LotterySystemWithCompletableFuture {

	@Resource
    private ThreadPoolExecutor executorService ;

    public static void main(String[] args) {
    

         // 创建10个异步抽奖任务
        List<CompletableFuture<String>> futures = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> {
                // 打印当前线程信息
                System.out.println("Current thread: " + Thread.currentThread().getName());
                return LotterySystem.drawLottery();
            }, executorService);
            futures.add(future);
        }

        // 使用allOf等待所有抽奖完成,并收集结果
        CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
        CompletableFuture<List<String>> resultsFuture = allFutures.thenApply(v -> 
            futures.stream()
                   .map(CompletableFuture::join)
                   .collect(Collectors.toList())
        );

        // 获取最终结果并打印
        List<String> results = resultsFuture.join();
        results.forEach(System.out::println);

        // 关闭线程池
        executorService.shutdown();
    }
}
相关推荐
减瓦6 分钟前
源码视图技术:集 APT 和 AST 所长
java·project lombok
兰令水16 分钟前
hot100【acm版】【2026.7.21打卡-java版本】
java·开发语言·算法·leetcode·面试
IT_Octopus18 分钟前
一次由 RestTemplate 引发的 Connection reset:被 XML 截胡的请求体
xml·java·spring boot
云烟成雨TD20 分钟前
Micrometer 系列【2】可观测性:指标(Metrics)
java·云原生·micrometer
2501_9142459326 分钟前
Java应用性能调优与生产监控部署:2026年实战手册
java·开发语言
吴声子夜歌29 分钟前
MongoDB 4.x——微服务入门
java·mongodb·微服务
好好沉淀43 分钟前
主键选择(自增 vs UUID vs 雪花算法)
java·算法
带刺的坐椅1 小时前
Solon AI:Tool 与 Talent 怎么选?从函数到领域专家
java·ai·llm·agent·solon
小白说大模型1 小时前
AI Agent 调试实战:链路追踪、Prompt 可视化与异常定位的系统方法
java·人工智能·python·算法·prompt