2 回答

TA貢獻(xiàn)1776條經(jīng)驗(yàn) 獲得超12個贊
同步不是完成這項工作的正確工具。你可以這樣做:
@RestController
public class SomeTask {
private SomeService someService;
private final AtomicBoolean isTriggered = new AtomicBoolean();
@Autowired
public SomeTask(SomeService someService) {
this.someService = someService;
}
@Async // requirement 1
@RequestMapping(method = RequestMethod.POST, path = "/triggerJob")
public void triggerJob() {
if (!isTriggered.getAndSet(true)) {
try {
expensiveLongRunningJob();
} finally {
isTriggered.set(false);
}
}
}
/**
* only runs once at a time, in the thread that sets isTriggered to true
*/
private void expensiveLongRunningJob() {
someService.executedJob();
}
}

TA貢獻(xiàn)1712條經(jīng)驗(yàn) 獲得超3個贊
對于要求 1,如果你只想使用@Async,你應(yīng)該在服務(wù)方法而不是控制器方法上使用它。但請注意,通過使其異步,您將失去對作業(yè)的控制,并且無法進(jìn)行故障處理,除非您通過實(shí)現(xiàn)接口來實(shí)現(xiàn)@Async和Future處理故障AsyncUncaughtExceptionHandler。
對于要求 3,您可以在服務(wù)中有一個 volatile 布爾字段,它在開始作業(yè)流程之前設(shè)置,并在作業(yè)流程完成后取消設(shè)置。在您的控制器方法中,您可以檢查服務(wù)的易失性布爾字段以確定作業(yè)是否正在執(zhí)行,如果作業(yè)正在進(jìn)行則返回適當(dāng)?shù)南?。另外,確保在處理AsyncUncaughtExceptionHandler接口實(shí)現(xiàn)失敗時取消設(shè)置布爾字段。
服務(wù):
@Service
public class SomeService {
public volatile boolean isJobInProgress = false;
@Async
public Future<String> executeJob() {
isJobInProgress = true;
//Job processing logic
isJobInProgress = false;
}
}
控制器:
@RestController
public class SomeTask {
@Autowired
private SomeService someService;
@RequestMapping(method = RequestMethod.POST, path = "/triggerJob")
public void triggerJob() {
if (!someService.isJobInProgress){
someService.executeJob(); //can have this in a sync block to be on the safer side.
} else {
return;
}
}
}
AsyncUncaughtExceptionHandler 的實(shí)現(xiàn):
public class CustomAsyncExceptionHandler implements AsyncUncaughtExceptionHandler {
@Autowired
private SomeService someService;
@Override
public void handleUncaughtException(
Throwable throwable, Method method, Object... obj) {
//Handle failure
if (someService.isJobInProgress){
someService.isJobInProgress = false;
}
}
}
@異步配置:
@Configuration
@EnableAsync
public class SpringAsyncConfig implements AsyncConfigurer {
@Override
public Executor getAsyncExecutor() {
return new ThreadPoolTaskExecutor();
}
@Override
public AsyncUncaughtExceptionHandler getAsyncUncaughtExceptionHandler() {
return new CustomAsyncExceptionHandler();
}
}
添加回答
舉報