我需要轮询数据库以获取特定结果。我无法在我的代码中继续,直到我得到预期的结果(除了传递超时间隔的情况)
步骤A - > Steb B - >第C步
这样做的简单方法(但对我来说不合适)是:
numOfRetry=0;
invokeStepA();
while(true)
{
numOfRetry++
boolen result=invokeStepB();
if(result || numOfRetry==3)
{
break;
}
else
{
Thread.sleep(100000)
}
invokeStepC();
在调用这些作业的时候,在我的Spring bean服务上使用while循环时感觉不对。
也许我可以更好地实现这一点?
谢谢。
关于我的流程的进一步解释:
步骤A是调用外部服务来做一些逻辑。
步骤B需要轮询另一项服务,检查步骤A是否完成了它的工作(如果已完成,我可以继续执行StepC,否则我需要在X秒内重试并再次检查)
StepC - 必须在StepB返回true后才能完成的另一个逻辑。
答案 0 :(得分:0)
以asynchronous
方式发生
int count = Runtime.getRuntime().availableProcessors();
ExecutorService threadPool = Executors.newFixedThreadPool(count);
invokeStepA();
for (int i = 0; i < RETRY_COUNT; i++) {
Future f = threadPool.submit(new Callable() {
@Override
public Object call() {
return invokeStepB();
}
}
result = (YOUR_DATA_STRUCTURE) f.get();
if (resultIsOK(result)) {
break;
}
}
但是,我认为既然您的任务是有序的,并且假设您不能去做其他事情,那么使用asynchronous
并不是那么有效。如果您有特殊要求,请告诉我有关您背景的更多信息。
编辑:我认为您的新要求看起来需要一种正确的方法来判断步骤A是否已经完成。因此,您可以使用CountDownLatch
检查A是否已正确完成。即
private final int count = Runtime.getRuntime().availableProcessors();
private final ExecutorService threadPool = Executors.newFixedThreadPool(count);
// invoke step A
invokeStepA();
// submit step B
final CountDownLatch latch = new CountDownLatch(1);
threadPool.submit(new Runnable() {
@Override
public void run() {
invokeStepB();
latch.countDown();
}
});
// wait for step B
boolean result;
try {
result = latch.await(TIME_OUT_IN_MILLISECONDS, TimeUnit.MILLISECOND);
} catch (InterruptedException e) {
}
// Check result
if (result) {
invokeStepC();
} else {
LOG.error("Timeout waiting for step A.");
}
这假定您的invokeStepA()
是阻止方法。
答案 1 :(得分:0)
以下是使用事件驱动方法的另一个想法。这只是我的想法,没有经过测试;)
import org.springframework.context.ApplicationEventPublisher;
@Service
public class JobA {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
@Scheduled(cron = "0 0 * * * ?")
public void doStepA() {
log.debug("some heavy lifting");
Object someData = ....;
applicationEventPublisher.publishEvent(new JobAEvent("Jo, I'm finished", someData));
}
}
@Service
public class JobB implements ApplicationListener<JobAEvent> {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
@Override
public void onApplicationEvent(final JobAEvent event) {
log.debug("do something more based on the event data");
Object someMoreData = ....;
applicationEventPublisher.publishEvent(new JobBEvent("Dude, me too", event.getSomeData(), someMoreData));
}
}
@Service
public class JobC implements ApplicationListener<JobBEvent> {
@Autowired
private ApplicationEventPublisher applicationEventPublisher;
@Override
public void onApplicationEvent(final JobBEvent event) {
log.debug("do even more work");
}
}
编辑: 您也可以直接调用该方法,然后同步运行。另一种可能性是使用&#39; @Async&#39;