java 简单实现异步

发布时间:2023年12月29日

首先在启动类上加上注解??

@EnableAsync 来开启异步

然后在实现类上给自己需要异步的方法加入异步注解?

@Async 

代码部分:
Controller
@RestController
@RequestMapping("demo/")
public class DemoController {

    @Resource
    private DemoService demoService;

    @ApiOperation("demo")
    @PostMapping("demo")
    public LaunchVo demo() throws InterruptedException {
        demoService.a();
        demoService.b();
        demoService.c();
        return null;
    }

}
Service
public interface DemoService {
    /**
     * 普通1
     * @throws InterruptedException
     */
    void a() throws InterruptedException;

    /**
     * 异步
     * @throws InterruptedException
     */
    void b() throws InterruptedException;

    /**
     * 普通2
     * @throws InterruptedException
     */
    void c() throws InterruptedException;

}
ServiceImpl
@Service
public class DemoServiceImpl implements DemoService {

    @Override
    public  void a() throws InterruptedException {
        for (int i = 0; i < 5; i++) {
            Thread.sleep(100);
            System.out.println("正常1:"+i);
        }
    }

    @Async
    @Override
    public  void b() throws InterruptedException {
        for (int i = 0; i < 5; i++) {
            Thread.sleep(100);
            System.out.println("异步:"+i);
        }
    }

    @Override
    public  void c() throws InterruptedException {
        for (int i = 0; i < 5; i++) {
            Thread.sleep(100);
            System.out.println("正常2:"+i);
        }
    }

}

运行结果

先执行的正常a方法,正常执行,在执行b和c的时候,正常是先要执行完b方法再执行c方法,因为b方法异步了,所以b,c两个方法结果成了交替,b方法异步执行

注意:直接使用?@Async 注解的线程池,默认的线程池无法实现线程重用,每次调用都会新建一条线程,会造成服务器占用内存过高,根据情况可以自己配置个线程池

代码

线程池配置

@Configuration
public class AsyncConfiguration {

    private int corePoolSize = 10;
    private int maxPoolSize = 100;
    private int queueCapacity = 100;
    private int KeepAliveSeconds = 200;
    private String namePrefix = "async-";

    @Bean(name = "asyncPoolTaskExecutor")
    public ThreadPoolTaskExecutor executor() {
        ThreadPoolTaskExecutor executor = new ThreadPoolTaskExecutor();
        //核心线程数
        executor.setCorePoolSize(corePoolSize);
        //线程池维护线程的最大数量,只有在缓冲队列满了之后才会申请超过核心线程数的线程
        executor.setMaxPoolSize(maxPoolSize);
        //缓存队列
        executor.setQueueCapacity(queueCapacity);
        //设置线程的空闲时间,当超过了核心线程出之外的线程在空闲时间到达之后会被销毁
        executor.setKeepAliveSeconds(KeepAliveSeconds);
        //异步方法内部线程名称
        executor.setThreadNamePrefix(namePrefix);
        /**
         * 当线程池的任务缓存队列已满并且线程池中的线程数目达到maximumPoolSize,如果还有任务到来就会采取任务拒绝策略
         * 通常有以下四种策略:
         * ThreadPoolExecutor.AbortPolicy:丢弃任务并抛出RejectedExecutionException异常。
         * ThreadPoolExecutor.DiscardPolicy:也是丢弃任务,但是不抛出异常。
         * ThreadPoolExecutor.DiscardOldestPolicy:丢弃队列最前面的任务,然后重新尝试执行任务(重复此过程)
         * ThreadPoolExecutor.CallerRunsPolicy:重试添加当前的任务,自动重复调用 execute() 方法,直到成功
         */
        //ThreadPoolExecutor.CallerRunsPolicy:重试添加当前的任务,自动重复调用 execute() 方法,直到成功
        executor.setRejectedExecutionHandler(new ThreadPoolExecutor.CallerRunsPolicy());
        //执行初始化
        executor.initialize();
        return executor;
    }
}

ServiceImpl

注解 @Async("asyncPoolTaskExecutor") 指定线程池bean?asyncPoolTaskExecutor

@Service
public class DemoServiceImpl implements DemoService {

    @Override
    public  void a() throws InterruptedException {
        for (int i = 0; i < 5; i++) {
            Thread.sleep(100);
            System.out.println("正常1:"+i);
        }
    }

    @Async("asyncPoolTaskExecutor")
    @Override
    public  void b() throws InterruptedException {
        for (int i = 0; i < 5; i++) {
            Thread.sleep(100);
            System.out.println("异步:"+i);
        }
    }

    @Override
    public  void c() throws InterruptedException {
        for (int i = 0; i < 5; i++) {
            Thread.sleep(100);
            System.out.println("正常2:"+i);
        }
    }

}

运行结果

使用自身配置的线程池,内存的问题就能得到控制

文章来源:https://blog.csdn.net/weixin_49834195/article/details/135269626
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。