gpt4 book ai didi

java - 避免同时执行两次 Spring @Async 任务

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:08:00 32 4
gpt4 key购买 nike

刚开始学习Spring Framework中的多线程,不知道怎么处理一个case。我有一个持久的操作,我不希望用户等待它完成,我发现有一个 @Async 注释将方法标记为异步可执行。

我的问题是什么是最好的方法来阻止这种方法,这样来自同一公司的用户就不能同时执行它。准确地说,我什至想阻止来自同一公司的用户同时执行 analyzeData(...)anlyzeStatistics(...)

我正在考虑使用 ConcurrentHashMap,用户公司作为键, boolean 值作为值,并在执行操作之前检查它。我想知道我的方向是否正确,或者 Spring 是否提供了其他更合适的选项。

@Service
public class LongOperationService {

@Async
public void analyzeData(User user, List<String> data) {
boolean operationResult = performLongOperation(data);
if (opeartionResult) {
log.info("Long operation ended successfully")
} else {
log.error("Long operation failure")
}
}

@Async
public void analyzeStatistics(User user, List<String> statistics) {
...
}

private void performLongOperation(List<String> data) {
// Just for demonstration
Thread.sleep(10000);
return true;
}
}

public class User {
String username;
String company;
}

最佳答案

您可以使用Semaphore 来限制访问资源的线程数。

因为你想阻止同一公司的用户同时访问你的分析功能,你应该为每个公司创建信号量:

// Init on startup
// Key should be a unique identifier to a company, I assume the `String company` as key, you should adjust as your real requirement
static final Map<String, Semaphore> COMPANY_ENTRANT = new ConcurrentHashMap<>();
// for each company
COMPANY_ENTRANT.put(companyId, new Semaphore(1));

现在为您服务:

@Async
public void analyzeData(User user, List<String> data) {
Semaphore entrant = COMPANY_ENTRANT.get(user.getCompany());
try {
entrant.acquire();
try {
boolean operationResult = performLongOperation(data);
if (opeartionResult) {
log.info("Long operation ended successfully")
} else {
log.error("Long operation failure")
}
} finally {
entrant.release();
}

} catch(InterruptedException e) {
...
}

}

如果你想延迟初始化 COMPANY_ENTRANT 映射,你可以使用 putIfAbsent:

 Semaphore entrant = COMPANY_ENTRANT.putIfAbsent(user.getCompany(), new Semaphore(1));

关于java - 避免同时执行两次 Spring @Async 任务,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51325249/

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