gpt4 book ai didi

java - Spring 3.x - @Async 方法不被任务执行器同时调用

转载 作者:行者123 更新时间:2023-12-02 11:17:17 24 4
gpt4 key购买 nike

我正在尝试在我的 Service 类中实现并发方法调用。

我的服务类中有一些注释为 @Async 的方法,并且我试图同时调用所有这些方法。但这些方法是按顺序执行的。

这是我的服务类别(虚拟):

@Service public class TestService {

public SomeDataType getSOmeDataType() {
try {
List<DataType> a = retrieveDataA().get();
List<DataType> b = retrieveDataB().get();
List<DataType> c = retrieveDataC().get();
List<DataType> d = retrieveDataD().get();
List<DataType> e = retrieveDataE().get();
}
catch (InterruptedException e) {
e.printStackTrace();
}
catch (ExecutionException e) {
e.printStackTrace();
}
return referralDetailsReferenceData;
}

@Async
private Future<List<DataType>> retrieveDataA() {
//method logic
}

@Async
private Future<List<DataType>> retrieveDataB() {
//method logic
}

@Async
private Future<List<DataType>> retrieveDataC() {
//method logic
}

@Async
private Future<List<DataType>> retrieveDataD() {
//method logic
}

@Async
private Future<List<DataType>> retrieveDataE() {
//method logic
}

这是我的 Spring 配置:

<bean id="executorService" class="java.util.concurrent.Executors" factory-method="newFixedThreadPool">
<constructor-arg value="10" />
</bean>

<task:executor id="threadPoolTaskExecutor" pool-size="10" />

<task:annotation-driven executor="executorService" />

当执行“getSomeDataType”时,会按顺序调用这些方法。

我对 @Async 和 Spring 中的并发执行很陌生,所以我确信我在做一些愚蠢的事情。但我无法弄清楚。

非常感谢任何建议。

最佳答案

问题是您在内部调用这些方法,因此它们不会被代理。为了使 @Async 工作,您需要从应用程序上下文中检索对象并调用检索到的副本上的方法。在内部调用它是行不通的。

如果您尝试调用内部 @Transactional 方法,也会发生同样的情况。请参阅Spring docs 末尾的注意: 部分。解释@Transactional以获取详细信息。

此外,您立即对 Future 返回值调用 .get() 的方式不正确。如果您希望它们并行发生,您应该提交所有任务,然后通过.get()检索每个任务。

处理代理问题的通常方法是创建一个单独的服务类,将 TestService 注入(inject)其中并直接调用 @Async 服务方法:

@Service public class TestServiceHelper {
@Autowired
TestService testService;

public SomeDataType getSOmeDataType() {
try {
// Invoke all of them async:
Future<List<DataType>> a = testService.retrieveDataA();
Future<List<DataType>> b = testService.retrieveDataA();
Future<List<DataType>> c = testService.retrieveDataA();
Future<List<DataType>> d = testService.retrieveDataA();
Future<List<DataType>> e = testService.retrieveDataA();

// Wait for each sequentially:
List<DataType> aList = a.get();
List<DataType> bList = b.get();
List<DataType> cList = c.get();
List<DataType> dList = d.get();
List<DataType> eList = e.get();

// do work with lists here ...
}
catch (InterruptedException e) {
e.printStackTrace();
}
catch (ExecutionException e) {
e.printStackTrace();
}
return referralDetailsReferenceData;
}
}

上述单独服务 bean 的替代方案(相当 hackish/不推荐!)是将对象注入(inject)自身并使用注入(inject)的副本来调用 @Async 方法。

关于java - Spring 3.x - @Async 方法不被任务执行器同时调用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17735455/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com