如何中断Java中的一系列过程?
我有一系列的过程需要连续执行,直到它们全部被执行,或者满足某个条件。以下是在满足条件之前需要执行的基本代码:如何中断Java中的一系列过程?,java,multithreading,exception,lejos-nxj,Java,Multithreading,Exception,Lejos Nxj,我有一系列的过程需要连续执行,直到它们全部被执行,或者满足某个条件。以下是在满足条件之前需要执行的基本代码: public boolean search() { robot.go(); robot.spin(); //etc - around 8 more similar commands (each takes around 2 seconds) return false; //didn't find what it was looking for } 到
public boolean search()
{
robot.go();
robot.spin();
//etc - around 8 more similar commands (each takes around 2 seconds)
return false; //didn't find what it was looking for
}
到目前为止,我想做我想做的事情的唯一方式是:
public boolean search()
{
robot.go(false);
while(robot.isMoving())
{
if(thingFound())
{
robot.stop()
return true;
}
Thread.yield();
}
robot.spin(false);
while(robot.isMoving())
{
if(thingFound())
{
robot.stop()
return true;
}
Thread.yield();
}
//etc - around 8 more similar commands
return false; //didn't find what it was looking for
}
false
参数到go()
和spin()
指示它们应该立即返回,以便检查条件。然而,这种方法给我的印象是相当低效,因为同一代码块必须重复10次。使用异常或并发线程可以更有效地实现这一点吗?不确定为什么要使用线程.yield()
-是否还有其他线程在执行,您没有提到?或者我误解了这个问题
我想也许命令模式可以在这里工作。您将拥有一个RobotCommand
接口和execute
方法,以及每个命令类型(go、spin等)的RobotCommand
实现。然后,您可以构造一个RobotAlgorithm
作为RobotCommand
的List
,并拥有一个方法executeRobotAlgorithm
,该方法在列表上迭代,对每个RobotCommand
调用execute
,并在每个RobotCommand
之后检查thingFound()
的结果
编辑-哦,我想我明白了。是否执行go
和spin
启动改变机器人状态的线程,或者类似的操作
编辑2-对于您的评论,这里的问题似乎是,如果机器人找到它要找的东西,您需要能够立即返回,但是
go
、spin
等命令现在无法执行,同时您需要能够继续执行新命令。因此,我在这里可能要做的是有两个线程——一个是“执行者”线程,它将逐个执行机器人命令的列表,另一个是“观察者”线程,它将反复睡眠和轮询(检查thingFound()
)。如果thingFound()
为真,则可以停止您的机器人以及执行器线程,或者如果执行器在thingFound()
为真之前到达末端,则它可以发出这样的信号(如有必要).机器人可以使用条件对象向控制器发出信号,表示它已完成某个子任务或进入新状态:
有趣的是,对于您所在的环境,您可能可以使用and,而不是更灵活的条件。控制器可以等待()直到机器人决定用notify()释放他。显然,while循环可以打包到自己的函数中:
private boolean isFound()
{
while (robot.isMoving())
{
if (thingFound())
{
robot.stop()
return true;
}
Thread.yield();
}
return false;
}
public boolean search()
{
robot.go(false);
if (isFound()) return true;
robot.spin(false);
if (isFound()) return true;
//etc - around 8 more similar commands
return false; //didn't find what it was looking for
}
(我不介意将条件拆分为两行;我可能会在生产代码中这样做。)
一个比我更好的Java程序员可以告诉你是否可以传递“过程”(在C编程中指向函数的指针)。我想你可以,但我不知道语法和规则。问题似乎是你不能(无论如何,大约在2004年)。基于乔纳森·莱夫勒的:
您可以使用Runnable作为指向命令的指针
private final Runnable going = new Runnable() {
@Override
public void run() {
robot.go(false);
}
});
private final Runnable spinning = new Runnable {
@Override
public void run() {
robot.spin(false);
}
});
// other commands
private boolean isFoundAfter(Runnable command)
{
command.run();
while (robot.isMoving())
{
if (thingFound())
{
robot.stop()
return true;
}
Thread.yield();
}
return false;
}
public boolean search()
{
if (isFoundAfter(going)) return true;
if (isFoundAfter(spinning)) return true;
//etc - around 8 more similar commands
return false; //didn't find what it was looking for
}
如果合适的话,进一步的步骤是将命令放入数组或列表中,并将其作为脚本执行
...
private boolean executeSearch(Runnable... commands)
{
for (Runnable cmd : commands) {
if (isFoundAfter(cmd)) return true;
}
return false; //didn't find what it was looking for
}
public boolean search() {
return executeSearch(going, spinning /* around 8 more similar commands */);
}
你想让这些while循环在给定的时间后超时吗?不。它们应该一直运行,直到robot.isMoving()
返回false
,因为之前的命令才完成。如果robot命令是go()、spin()等方法,你可以使用反射来编写命令,这样代码会更短。这是正确的。在没有参数的情况下调用时,while(robot.isMoving())Thread.yield()代码>包含在函数中。当使用true
调用时,线程将启动,但过程不会等待其完成。我没有想到使用列表。让一个局部布尔变量interrupted
在执行之间进行检查-如果interrupted
为true,则退出主循环。覆盖interrupt()
方法以设置interrupt
。当您想要停止执行器线程时,在执行器线程上调用interrupt()
。遗憾的是,条件类在我必须使用的有限Java子集中不可用。对于乐高机器人控制器,我使用的语言(LeJOS NXJ)是Java的一个相当有限的子集。@danben:感谢您的进一步确认;正如你所看到的,我通过可靠的谷歌搜索找到了同样的东西。(总有一天,我会再次尝试Bing,看看它是否能提供更好的答案——但到目前为止,它对我没有多大帮助。Wolfram Alpha从未屈尊承认我的任何问题是有效的。显然,我不是他们的目标受众。)对——在我留下评论的时候,你还没有进行编辑。如果我好像踩了你的脚,我很抱歉。这就是SO.NP danben的方式——正如时间所示,在我编辑我的答案时,您正在键入注释(我看到您现在已经删除了注释,因此时间不再显示)。你所做的就是让我不用花太多时间去研究Java是否已经改变了。我试过冰;在后来的一个页面上(我认为是2或3页,与谷歌第一个页面的一半相比),发现了一些关于同样事情的最新证据。