要修改的原始程序代码:
/ 定期调用此方法,它从db获取数据,对其执行一些操作,并将结果放入一个文件中,该文件在所有处理结束时通过ftp发送 /
void pullData(){
while(!stopped){
rows= getRowsFromDb();
for (row: rows){
newRow= process(row);
rowsContainer.add(newRow)
}
writeToFile(rowsContainer);
sendFileSomewhere();
}
}
现在必须修改此代码以允许向其发出以下命令:仅处理1行;跳过1行(稍后会有更多命令)。为此,应用程序处于挂起模式,它将不会处理行,直到它获得上面列出的2个命令之一。此外,它可以从暂停模式恢复,然后恢复正常处理。
问题不在于如何做到这一点,但是正确的方法是什么。
(1)有人为每个操作建议了布尔标志。这是一个非常糟糕的主意。我建议人们避免使用标志有很多原因(有些人可能已经讨论过堆栈溢出)。
(2)另一个想法是为命令使用isSuspended和枚举的bool标志。这比(1)好,但不是很多,因为应用程序需要检查哪个命令是最后一个,以及它是否处于挂起模式并且正常运行。
(3)我正在考虑拆分应用程序并使用策略模式。每个命令都会在应用程序中获得它自己的方法。这有点复杂,但对我来说似乎更清洁。
你会建议什么(你不需要从我列出的选项中选择,我想听听你是如何处理类似情况的)?
答案 0 :(得分:2)
我会使用ExecutorService执行
等任务private Future lastTask = null;
// only run one task at a time.
if (lastTask != null) lastTask.cancel(true);
lastTask = executorService.submit(new ProcessOnRowRunnable());
// or
lastTask = executorService.submit(new ProcessPendingRowsAndStopRunnable());
// or
lastTask = executorService.submit(new ProcessAllRowsUntilCancelledRunnable())
// later
future.cancel(true);
注意:你的循环必须遵守中断,否则它们不会因为线程被中断而停止。你可以使用
while(conditions && !Thread.curentThread().isInterrupted()) {
// do work
}
答案 1 :(得分:1)
我认为您需要传递消息的ITC:
while true
msg = getMsgFromQueue
case msg
skipARow: skip();
processARow: process();
doSomethingElse:
答案 2 :(得分:1)
在使用有限状态机(或基于枚举的简单状态驱动的子集)之前,我已经做了很多次 - 最大的好处是你可以验证你的FSM并保持一些不受管理的东西。 大量的旗帜问题
图3.简单状态图:(来自here)
我个人使用FSM管理可应用于对象的操作(在本例中为Orders),管理RFC-822电子邮件消息的解析,控制硬件;
状态驱动循环的一个非常简单但功能性的例子:
state = S_Starting;
while(state != S_Finished){
switch (state){
case S_Starting:
// do something
state = S_Running;
break;
case S_Running
rows= getRowsFromDb();
for (row: rows){
newRow= process(row);
rowsContainer.add(newRow)
}
state = S_HandleReceipt;
break;
case S_HandleReceipt:
writeToFile(rowsContainer);
sendFileSomewhere();
case S_Paused:
if (some_other_test){
state = S_Running;
}
break;
}
if (some_test_for_finished) {
state = S_Finished;
} else if (some_test_for_pause) {
state = S_Paused;
}
}
参考:
C#Hierarchical State Machine Stateless遗憾地还没有移植到Java,但却是一个很好的工具 - 我已经多次使用它了,它很棒。