spring中异步执行的方式。

时间:2021-08-06
本文章向大家介绍spring中异步执行的方式。,主要包括spring中异步执行的方式。使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

同步执行和异步线程池的方式执行和springboot中使用@Async加@EanbleAsync的方式对比。

1.同步执行:

@RestController
public class TestController {
    @Autowired
    private TestService service;

    /**@
     * 使用传统方式测试
     */
    @GetMapping("/test")
    public void test() {
        System.out.println("获取主线程名称:" + Thread.currentThread().getName());
        service.serviceTest();
        System.out.println("执行完成,向用户响应成功信息");
    }
}
@Service
public class TestService {

    public void serviceTest() {
        // 这里执行实际的业务逻辑,在这里我们就是用一个简单的遍历来模拟
        Arrays.stream(new int[]{1,2,3,4,5,6,7,8,9,10}).forEach(t -> {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("获取number为:" + t) ;
        });
    }
}
输出的结果为:
获取主线程名称:http-nio-8080-exec-2
获取number为:1
获取number为:2
获取number为:3
获取number为:4
获取number为:5
获取number为:6
获取number为:7
获取number为:8
获取number为:9
获取number为:10
执行完成,向用户响应成功信息
先执行方法,执行完成方法中的循环之后再返回响应信息。

2.异步线程池执行:

@RestController
public class TestThreadController {

    @Autowired
    private TestThreadService threadService;
    /**
     * 使用传统方式测试
     */
    @GetMapping("/test")
    public void test() {
        System.out.println("获取主线程名称:" + Thread.currentThread().getName());
        /**
         *  这里也可以采用以下方式使用,但是使用线程池的方式可以很便捷的对线程管理(提高程序的整体性能),
         *  也可以减少每次执行该请求时都需要创建一个线程造成的性能消耗
         *  new Thread(() ->{
         *  run方法中的业务逻辑
         *  })
         */

        /**
         * 定义一个线程池
         * 核心线程数(corePoolSize):1
         * 最大线程数(maximumPoolSize): 1
         * 保持连接时间(keepAliveTime):50000
         * 时间单位 (TimeUnit):TimeUnit.MILLISECONDS(毫秒)
         * 阻塞队列 new LinkedBlockingQueue<Runnable>()
         */
        ThreadPoolExecutor executor = new ThreadPoolExecutor(1,5,50000, TimeUnit.MILLISECONDS, new LinkedBlockingQueue<Runnable>());
        // 执行业务逻辑方法serviceTest()
        executor.execute(new Runnable() {
            @Override
            public void run() {

          threadService.serviceTest();
            }
        });
        System.out.println("执行完成,向用户响应成功信息");
    }
}
TestThreadService和TestService的内容一样不在重复写。
输出结果:
获取主线程名称:http-nio-8080-exec-2
执行完成,向用户响应成功信息
获取number为:1
获取number为:2
获取number为:3
获取number为:4
获取number为:5
获取number为:6
获取number为:7
获取number为:8
获取number为:9
获取number为:10
直接返回响应信息,然后执行方法中的循环。


3.spring的注解@Async和@EableAsync:

@RestController
public class TestAsyncController {

    @Autowired
    private TestAsyncService asyncService;

    /**
     * 使用传统方式测试
     */
    @GetMapping("/testAsync")
    public void test() {
        System.out.println("获取主线程名称:" + Thread.currentThread().getName());
        asyncService.serviceTest();
        System.out.println("执行完成,向用户响应成功信息");
    }

}
@Service
@EnableAsync
public class TestAsyncService {

    @Async
    public void serviceTest() {
        // 这里执行实际的业务逻辑,在这里我们就是用一个简单的遍历来模拟
        Arrays.stream(new int[]{1,2,3,4,5,6,7,8,9,10}).forEach(t -> {
            try {
                Thread.sleep(100);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println("获取number为:" + t) ;
        });
    }
}
输出结果:
获取主线程名称:http-nio-8080-exec-2
执行完成,向用户响应成功信息
获取number为:1
获取number为:2
获取number为:3
获取number为:4
获取number为:5
获取number为:6
获取number为:7
获取number为:8
获取number为:9
获取number为:10
同样直接返回响应信息,然后执行方法中的循环。
@Async标记方法之后表示这是个异步方法,@Async必须和@EableAsync一起使用,否者不起作用,
在使用@Async的使用也是可以自己定义线程池。
其实异步的方式也可以用消息队列来实现。
 

原文地址:https://www.cnblogs.com/zqk9412/p/15107301.html