如何在Java中中断一系列过程?

时间:2010-01-09 18:57:50

标签: 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(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
}

falsego()的{​​{1}}参数表示它们应立即返回,以便检查条件。但是,这种方法对我来说效率相当低,因为相同的代码块必须重复10次。使用异常或并发线程可以更有效地实现这一点吗?

4 个答案:

答案 0 :(得分:3)

不确定您使用Thread.yield()的原因 - 是否有其他线程正在执行而您没有提及?或许我误解了这个问题。

我想也许Command模式可以在这里工作。您将拥有RobotCommand接口和execute方法,并且每个命令类型(go,spin等)实现RobotCommand。然后,您可以将RobotAlgorithm构建为List RobotCommand,并使用方法executeRobotAlgorithm迭代列表,在每个{{1}上调用execute每个人之后检查RobotCommand的结果。

编辑 - 哦,我想我明白了。 thingFound()go是否会启动改变机器人状态的线程,或类似的东西?

编辑2 - 为了回应您的评论,听起来这里的问题是,如果机器人找到了它正在查找的内容,您需要能够立即返回,但是{{1} },spin等命令现在不会执行此操作,并且您需要能够在此期间继续执行新命令。所以我在这里可以做的是有两个线程 - 一个是“执行者”线程,它将逐个执行go spin个帖子,以及一个将重复睡眠的“观察者”线程民意调查(检查List)。如果RobotCommand为真,那么你可以停止你的机器人以及执行程序线程,或者如果执行程序在thingFound()为真之前到达终点,那么它就可以发出信号(如果需要的话)。 / p>

答案 1 :(得分:2)

显然,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编程而言)。 我怀疑你可以,但我不知道语法和规则。 evidence似乎是你不能(大约2004年,无论如何)。

答案 2 :(得分:0)

机器人可以使用Condition对象向控制器发出信号,告知它已完成某个子任务或进入新状态:

http://java.sun.com/j2se/1.5.0/docs/api/java/util/concurrent/locks/Condition.html

有趣的是,对于您可能使用的环境而言notify()wait()而不是更灵活的条件。控制器可以等待()直到机器人决定用notify()释放他。

答案 3 :(得分:0)

基于Jonathan Leffler的answer
您可以将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 */);
}
相关问题