这半年来一直组里的项目基本架构是Spring MVC,从中学到的不少关于Spring尤其是Annotation的使用,最近碰到的一个问题是在Spring中做Multi-threading的问题,其实如果没有在框架里做multi-threading是一个很Core java的知识点,无非是用runnable用Thread然后加上那几个wait,join,sleep等等方法。然而经过测试发现Spring偏偏有是有默认的执行顺序,不受外界这些个线程的方法的影响,可能跟Spring创建的bean的scope有关系,要改的的话可能有办法,类似于在annotation里改个什么变量,或是config文件里改个什么bean的创建设置或属性,但由于并不想改太多的现有框架结构和业务流程,所以对Spring本身自带的multi-threading的功能进行了一个小粗浅的研究和运用。
主要就是@Async这个annotation的使用,由于编程都是完成功能为目的,所以只是基于这次的任务使用到了的部分进行展示,深的东西没有过多追究。
首先要用到这个annotation,前提Spring的各种环境配置一定是要弄好的,在context config要加上annotation driven的config bean,要在web.xml注册好Spring的listener什么的就不说了,还不会的可以自己搜搜到处都是,然后就是在一个bussiness bean里使用了,举例说明,比如一个service类,有一个方法是向调用DAO进而向database发出query,如下
public class QueryService{
private QueryDao query;
public Object doQuery(String queryName){
return query.getQuery();
}
}
如果用到Spring对这个bean inject基础上,要加入multi-threading就不那么直接了,如果再用core java 那一套Spring会无视之,所以要在方法上面加上一个@Async,如下:
@Service
public class QueryService{
private QueryDao query;
@Async
public Object doQuery(String queryName){
return query.getQuery();
}
}
这样做就能使多次的调用成为多线程同步执行了,然而测试发现,标注@Async的方法只能在别的类里被调用才能实现多线程,鉴于此,我们最好是新建一个Wrapper类去实现,把这个类做为如果要使用多线程时才调用的类
@Service
public class QueryWrapper{
private QueryService queryService;
@Async
public Object doQueryAsych(String queryName){
try {
Thread.sleep(15000);
} catch (InterruptedException e) {
e.printStackTrace();
}
return queryService.doQuery();
}
}
别忘记了在context里加上Spring的task管理bean,可以对thread pool的大小等等去设置
<task:annotation-driven executor="executor" />
<task:executor id="executor" pool-size="7"/>
到这一步,基本就能利用Spring的多线程管理调用了,但只是单纯的多线程执行一个无返回值的的方法,接下来的问题就是对方法返回值的处理了,怎么去实现callback的功能,这时就要用到Future接口了,这个接口在java.util.concurrent.Future;里,以及Future类的实现类AsyncResult<T>,道理很明显,就是把原本的返回值用AsyncResult来注册返回,再用futurn.get();这个方法去等待返回值的,所谓的callback就完成了,下面的代码是调用上述的wrapper类中的方法对返回值的收集处理:
public class Helper{
private QueryWrapper wrapper;
public List<Object> getObject(String[] queryNames){
List<Object> result = new ArrayList<Object>();
List<Future<Object>> futures = new ArrayList<Future<Object>>();
//get each future object after firing the
for(String queryName : queryNames){
future.add(wrapper.doQueryAsych(queryName ));
}
//call back part
for(String future : futures){
//wait future's return value and add into result list
result(future.get());
}
return result;
}
}
code都是我手敲的,如果有typo请别喷,基本原理就是这样,用Future作为callback的载体,用futurn.get()这个方面去等待并得到各个不同线程返回的的值,核心点就是这么多,接下来就是要完善一下代码就行了。
希望对你有帮助
分享到:
相关推荐
JAVA 中Spring的@Async用法总结 在 Java 应用中,绝大多数情况下都是通过同步的方式来实现交互处理的...以上就是 Spring 中 @Async 的用法总结,通过使用 @Async 可以轻松地实现异步调用,提高系统的响应速度和性能。
以下是如何在测试中使用`Future`来检查异步任务状态并处理超时: ```java @Slf4j @RunWith(SpringJUnit4ClassRunner.class) @SpringBootTest public class ApplicationTests { @Autowired private Task task; ...
浅谈Spring @Async异步线程池用法总结 本文主要介绍了Spring @Async异步线程池的用法总结,包括异步线程池的接口类、@Async定义异步任务、Spring开启异步配置等内容。 1. 异步线程池的接口类 Spring提供了多种...
现在,我们可以在Service类中使用@Async注解来异步化方法。例如: ```java @Service public class BusinessService { private static final Logger log = LoggerFactory.getLogger(BusinessService.class); @...
在Spring Boot中,我们可以使用`@Async`注解将同步方法转换为异步方法。 2. **SpringBoot中的@Async** 要使用`@Async`,首先需要配置一个`TaskExecutor`。Spring Boot默认提供了一个简单的线程池配置,如果需要...
在Spring Boot框架中,@Async注解是实现异步任务处理的关键工具,它允许开发者将耗时的操作从主线程中分离出来,以提高应用程序的响应速度。本文将深入探讨@Async的工作原理、配置方法以及使用场景,帮助你更好地...
【Spring中@Async用法详解及简单实例】 在Spring框架中,@Async注解用于实现异步方法调用,这是Spring 3.x引入的一个特性,旨在简化多线程编程,提高应用程序的性能和响应速度。在传统的同步调用中,程序会按照顺序...
在Spring Boot应用中,`@Async`注解是Spring框架提供的异步处理功能,它使得开发者可以方便地实现非阻塞式编程,提高应用程序的执行效率。然而,很多初学者在使用`@Async`时可能会遇到一些误区,导致程序运行结果不...
本文将详细介绍Spring框架中的@Async注解,并深入理解其在解决异步调用问题中的应用。通过示例代码和详细的解释,帮助读者更好地理解@Async的使用和原理。 一、异步调用和同步调用 异步调用和同步调用是两种不同的...
在Spring Boot应用中,使用线程池和异步处理是提高系统并发性能和响应速度的重要手段。`@Async`注解是Spring提供的一个特性,用于标记方法为异步执行,这样可以避免主线程等待耗时的操作,提高系统效率。本文将详细...
总结,`@Scheduled`任务调度是Spring Boot中实现定时任务的关键,它可以配合多线程和`@Async`异步任务提升程序的并发性能。通过自定义线程池和配置`TaskExecutor`,我们可以更好地控制任务的执行方式,从而优化应用...
Spring Boot 提供了 @Async 注解,可以将方法异步化,使得方法的调用者不需要等待方法的执行结果,直接返回,而方法的实际执行将提交给 Spring 的 TaskExecutor 中,由指定的线程池中的线程执行。 2. TaskExecutor...
下面将详细解释如何在Spring Boot中使用`@Async`实现异步调用,以及其背后的原理。 首先,要启用`@Async`注解的功能,需要在Spring Boot的主配置类上添加`@EnableAsync`注解。这会告诉Spring框架,你需要异步任务的...
接下来,我们将深入探讨如何在Spring Boot中使用`@Async`进行异步任务调用。 首先,我们需要理解同步调用与异步调用的区别。同步调用是一种顺序执行的方式,每一个方法必须等待前一个方法执行完毕后才能继续执行。...
对于异步方法,Spring会在bean初始化时创建一个Executor服务,并将bean的方法调用包装成Future任务提交到Executor中。 现在,让我们回到问题的核心:当一个bean(如`TransationServiceImpl`)中存在循环依赖,并且...
默认情况下,@Async 注解使用代理模式来处理异步调用,但这只能拦截代理的调用,而不能拦截同一个类中的方法调用。如果需要拦截同一个类中的方法调用,需要使用 AspectJ 模式。 6. 同一个类中的方法调用 需要注意...
在 Spring 框架中,Async 注解是一个非常重要的功能,它可以帮助我们实现异步操作,从而提高系统的性能和响应速度。在本文中,我们将详细介绍 Spring里的Async注解实现异步操作的方法步骤,并通过示例代码来演示异步...
在Spring Boot中,启用`async`异步调用是一项关键功能,它允许应用程序在处理请求时启动一个后台任务,而不必等待该任务完成。这在处理耗时操作时尤其有用,如大数据计算、发送电子邮件或文件上传等。下面将详细阐述...
Spring Boot 中使用多线程的方式有很多种,最简单的方式就是使用 @Async 注解来实现。下面我们将详细介绍如何使用 @Async 注解来实现多线程编程。 多线程前言 在 Java 中,多线程编程是非常重要的一种技术,通过...
在Spring Boot应用中,`@Async`注解用于实现异步方法执行,这极大地提高了应用程序的并发性能。本文将深入探讨`@Async`的工作原理、使用场景以及如何配置和测试。 1. **异步注解的启用** 使用`@EnableAsync`注解在...