Pregunta

Tengo un montón de los procedimientos que necesitan ser ejecutadas sucesivamente hasta que todos ellos son ejecutados, o se cumple una determinada condición. Aquí está el código básico que necesita ser ejecutado hasta que se cumpla una condición:

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
}

Hasta ahora, la única manera que he pensado de hacer lo que quería es la siguiente:

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
}

El parámetro false a go() y spin() indica que deben volver inmediatamente, permitiendo la condición de comprobación. Sin embargo, este enfoque me parece bastante ineficiente, ya que el mismo bloque de código debe ser repetido 10 veces. Podría esto se alcanza más eficientemente con las excepciones o hilos concurrentes?

¿Fue útil?

Solución

de Jonathan Leffler :
se puede utilizar un Ejecutable como puntero a los comandos

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
}


un paso más, en su caso, poner el comandos en una matriz o una lista y ejecutarlo como un script

...

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 */);
}

Otros consejos

Hay otros hilos de ejecución que usted no mencionó -

No está seguro de por qué está utilizando Thread.yield()? O tal vez leí mal el problema.

Creo que tal vez el patrón de comandos podría trabajar aquí. Se podría tener una interfaz con un método RobotCommand execute, y una implementación de RobotCommand según el tipo de comando (vaya, giro, etc.). Posteriormente, se podría construir una RobotAlgorithm como List de RobotCommand, y tienen un executeRobotAlgorithm método que itera sobre la lista, llamando execute en cada RobotCommand y comprobando el resultado de thingFound() después de cada uno.

Editar - Oh, creo que lo entiendo. No go y spin dar comienzo a las discusiones que cambian el estado del robot, o algo por el estilo?

Editar 2 - en respuesta a su comentario, parece que el problema aquí es que usted necesita para ser capaz de volver de inmediato si el robot encuentra lo que está buscando, pero el go, spin, comandos etc no van a hacer esto ahora, y lo que necesita la capacidad de mantener la ejecución de nuevos comandos en el ínterin. Así que lo que podría hacer aquí es tener dos hilos - uno podría ser un "ejecutor" hilo que ejecutar su List de RobotCommands uno por uno, y un hilo "vigilante" que se va a dormir y sondeo (marque thingFound()) varias veces. Si thingFound() es siempre cierto, entonces puede detener el robot, así como el hilo ejecutor, o si el ejecutor llega al final antes de thingFound() es verdad, entonces puede indicar como tal (si es necesario).

Claramente, el bucle while puede ser empaquetado en su propia función:

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
}

(No me importa si el condicional se divide en dos líneas;. Probablemente haría que en el código de producción)

Una mejor programador de Java que te puedo decir si se puede pasar de todo 'procedimientos' (punteros a funciones, en términos de programación C). sospecho que pueda, pero no sé la sintaxis y reglas. La pruebas parece ser que no se puede (alrededor del año 2004, de todos modos).

robot puede utilizar un objeto de condición de señal al controlador que ha completado algunos sub-tarea o entró en un nuevo estado:

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

interesante, para el medio ambiente que está en que probablemente se podría usar y notificar () y wait () en lugar de la condición más flexible. controlador podría esperar () hasta que el robot decide liberar él con notificar ().

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top