我有一个功能
@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);
}
}
}
这将从数据库中检索所有处于待处理状态的下载请求。这只是downloadrequest表中的一个枚举。
@Async
public void processDownloadRequest(DownloadRequest downloadRequest) {
accountProfileProcessor.run(downloadRequest);
}
在accountProfileProcessor内部,downloadRequest的状态变为InProgress。
@Scheduled函数运行并获取为异步作业提交的downloadRequest,但状态尚未切换为inProgress时,就会出现竞争条件。如何避免这种情况?
如果@Async taskexecutor队列为空但无法使其正常工作,我试图仅在@Scheduled函数中运行代码
答案 0 :(得分:1)
以下内容将防止两次并发尝试下载同一资源。
请注意,如果需要确保不重复执行相同下载的后续尝试,则需要某种形式的跟踪来完成较长的时间,以某种方式防止内存泄漏(例如,不要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());
}
}
}