java-开启多线程的几种方式及案例

本文介绍了Java中实现多线程的三种方式:使用Runable接口、Thread类以及SpringBoot中的@Async注解。通过实例展示了如何创建和管理线程,以及如何在SpringBoot应用中实现异步任务执行。同时,还演示了如何配置和使用线程池,确保异步任务的高效执行。
摘要由CSDN通过智能技术生成

一:Runable实现多线程创建方式

public static void main(String[] args) throws Exception{

    System.out.println("主线程 =====> 开始 =====> " + System.currentTimeMillis());

    new Thread(() -> {
        System.out.println("异步线程 =====> 开始 =====> " + System.currentTimeMillis());
        try{
            Thread.sleep(5000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("异步线程 =====> 结束 =====> " + System.currentTimeMillis());
    }).start();

    Thread.sleep(2000);

    System.out.println("主线程 =====> 结束 =====> " + System.currentTimeMillis());
    
}

二:Thread
因为异步任务的实现本质的由新线程来执行任务,所以通过线程池的也可以实现异步执行。写法同我们利用线程池开启多线程一样。但由于我们的目的不是执行多线程,而是异步执行任务,所以一般需要另外一个线程就够了。

因此区别于执行多线程任务的我们常用的newFixedThreadPool,在执行异步任务时,我们用newSingleThreadExecutor 来创建一个单个线程的线程池。

public static void main(String[] args) throws Exception{

    System.out.println("主线程 =====> 开始 =====> " + System.currentTimeMillis());

    ExecutorService executorService = Executors.newSingleThreadExecutor();
    executorService.submit(()->{
        System.out.println("异步线程 =====> 开始 =====> " + System.currentTimeMillis());
        try{
            Thread.sleep(5000);
        }catch (InterruptedException e){
            e.printStackTrace();
        }
        System.out.println("异步线程 =====> 结束 =====> " + System.currentTimeMillis());
    });
    executorService.shutdown(); // 回收线程池

    Thread.sleep(2000);

    System.out.println("主线程 =====> 结束 =====> " + System.currentTimeMillis());
    
}

三:@Async注解
我们都知道,SpringBoot项目有一个的很重要的特点就是的注解化。如果你的项目是SpringBoot,那就又多了一种选择——@Async注解。

使用起来也非常简单,将要异步执行的代码封装成一个方法,然后用@Async注解该方法,然后在主方法中直接调用就行。
也可以自己配置下线程池

    @Bean(name = "asyncTaskExecutor")
    public Executor asyncTaskExecutor() {
        logger.info("--------------start asyncTaskExecutor------------------------");
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        executor.setCorePoolSize(50);
        executor.setMaxPoolSize(200);
        executor.setQueueCapacity(100);
        executor.setThreadNamePrefix("async-task-");
        executor.setKeepAliveSeconds(30);
        executor.setWaitForTasksToCompleteOnShutdown(true);
        executor.setAwaitTerminationSeconds(60);
        // rejection-policy:当pool已经达到max size的时候,如何处理新任务
        // CALLER_RUNS:不在新线程中执行任务,而是有调用者所在的线程来执行
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //执行初始化
        executor.initialize();
        return executor;
    }

使用时直接加上注解:

    @Async("asyncTaskExecutor")
    public void deleteFile(List<String> fileIdList) {
        if (fileIdList==null || fileIdList.size()<1){
            return;
        }
        logger.info("---异步执行-文件删除,待删除文件{}个---",fileIdList.size());
        fileIdList.forEach(s -> {
            try {
                fileService.deleteFileByFileId(s);
                logger.info("文件{}删除完成",s);
            }catch (Exception e){
                logger.error("文件{}删除时异常",s,e);
            }
        });
    }

也可以这样使用

    @Autowired
    @Qualifier("asyncTaskExecutor")
    ThreadPoolTaskExecutor executor;

    public static void main(String[] args) {
        
        //开启 异步 多线程
        executor.execute(() -> {
            try {
                //归档
                reqArchiveSystemService.postToArchiveSystem(contract);
            } catch (Exception e){
                logger.error("归档失败,使用原因:{}",e);
            }finally {
                jedisUtil.incrCount("transfer:count");
            }
        });
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值