gpt4 book ai didi

java - 如何防止调度程序中调用异步函数的竞争条件?

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

我有一个函数

  @Scheduled(fixedDelayString = "2000")
public void processPendingDownloadRequests() {
List<DownloadRequest> downloadRequests = downloadRequestService.getPendingDownloadRequests();
for (int i = 0; i < downloadRequests.size(); i++) {
DownloadRequest downloadRequest = downloadRequests.get(i);
processDownloadRequest(downloadRequest);
}

}
}

这将从数据库中检索所有处于待处理状态的下载请求。这只是下载请求表中的一个枚举。

    @Async
public void processDownloadRequest(DownloadRequest downloadRequest) {
accountProfileProcessor.run(downloadRequest);
}

在 accountProfileProcessor 内部,downloadRequest 的状态更改为 InProgress。

当 @Scheduled 函数运行并获取已为异步作业提交的 downloadRequest 但状态尚未切换为 inProgress 时,就会出现竞争条件。我怎样才能避免这种情况?

如果 @Async taskexecutor 队列为空,但无法使其工作,我尝试仅运行 @Scheduled 函数内的代码

最佳答案

以下内容将阻止两次并发尝试下载同一资源。

请注意,如果需要确保不重复执行相同下载的后续尝试,则需要某种形式的更长时间的跟踪完成情况,并且需要以某种方式防止内存泄漏(即不要' t 将所有完整的 id 无限期地保留在内存中)。

private Set<String> activeDownloads = new HashSet<>();

@Async
public void processDownloadRequest(DownloadRequest downloadRequest) {
synchronized(this.activeDownloads) {
if (this.activeDownloads.contains(downloadRequest.getId()) {
// Duplicate download attempt - log it?
return;
} else {
this.activeDownloads.put(downloadRequest.getId());
}
}


try {
accountProfileProcessor.run(downloadRequest);
} finally {
synchronized(this.activeDownloads) {
this.activeDownloads.remove(downloadRequest.getId());
}
}
}

关于java - 如何防止调度程序中调用异步函数的竞争条件?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59184340/

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