基于线程池和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();
    }
}
相关推荐
半夏陌离2 分钟前
SQL 实战指南:电商订单数据分析(订单 / 用户 / 商品表关联 + 统计需求)
java·大数据·前端
我真的是大笨蛋17 分钟前
K8S-Pod(上)
java·云原生·容器·kubernetes
纪元A梦41 分钟前
贪心算法应用:数字孪生同步问题详解
java·算法·贪心算法
Micrle_0071 小时前
java分布式场景怎么实现一个高效的 读-写锁
java·分布式
海上生明月丿1 小时前
微服务01
java·spring boot·微服务
coooliang2 小时前
【鸿蒙 NEXT】V1迁移V2状态管理
java·前端·harmonyos
Luke Ewin2 小时前
FunASR的Java实现Paraformer实时语音识别 | 一款无需联网的本地实时字幕软件
java·人工智能·语音识别·asr·funasr·paraformer·sensevoice
叫我阿柒啊2 小时前
从Java全栈到前端框架的全面实战:一次真实面试的深度解析
java·spring boot·缓存·微服务·消息队列·vue3·rest api