如何中断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页,与谷歌第一个页面的一半相比),发现了一些关于同样事情的最新证据。