2 回答
TA贡献1776条经验 获得超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贡献1712条经验 获得超3个赞
对于要求 1,如果你只想使用@Async,你应该在服务方法而不是控制器方法上使用它。但请注意,通过使其异步,您将失去对作业的控制,并且无法进行故障处理,除非您通过实现接口来实现@Async和Future处理故障AsyncUncaughtExceptionHandler。
对于要求 3,您可以在服务中有一个 volatile 布尔字段,它在开始作业流程之前设置,并在作业流程完成后取消设置。在您的控制器方法中,您可以检查服务的易失性布尔字段以确定作业是否正在执行,如果作业正在进行则返回适当的消息。另外,确保在处理AsyncUncaughtExceptionHandler接口实现失败时取消设置布尔字段。
服务:
@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 的实现:
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();
}
}
添加回答
举报