문제

나는 모두 실행되거나 특정 조건이 충족 될 때까지 연속적으로 실행 해야하는 많은 절차가 있습니다. 조건이 충족 될 때까지 실행 해야하는 기본 코드는 다음과 같습니다.

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 번 반복되어야하므로 비효율적이라고 생각합니다. 예외 나 동시 스레드로 더 효율적으로 달성 될 수 있습니까?

도움이 되었습니까?

해결책

Jonathan Leffler의 기반 대답:
런 가능성을 사용할 수 있습니다 바늘 명령에

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

다른 팁

왜 사용 중인지 잘 모르겠습니다 Thread.yield() - 언급하지 않은 다른 스레드가 있습니까? 아니면 문제를 잘못 읽었을 수도 있습니다.

명령 패턴이 여기서 작동 할 수 있다고 생각합니다. 당신은 가질 것입니다 RobotCommand An과 인터페이스 execute 방법 및 구현 RobotCommand 명령 유형 당 (이동, 스핀 등). 그런 다음 a를 구성 할 수 있습니다 RobotAlgorithm A로 ListRobotCommand, 방법이 있습니다 executeRobotAlgorithm 목록 위에 반복되어 전화를 걸었습니다 execute 각각에 RobotCommand 그리고 결과를 확인합니다 thingFound() 각각 후.

편집하다 - 오, 내가 얻는 것 같아요. 하다 go 그리고 spin 로봇의 상태를 바꾸는 스레드를 시작하십시오.

편집 2 - 귀하의 의견에 대한 응답으로, 여기서 문제는 로봇이 찾고있는 것을 찾으면 즉시 반환 할 수 있어야한다는 것입니다. go, spin, ETC 명령은 지금이 작업을 수행하지 않으며 그 동안 새로운 명령을 계속 실행할 수있는 기능이 필요합니다. 그래서 내가 여기서 할 수있는 것은 두 개의 스레드가 있습니다. 하나는 당신을 실행할 "집행자"스레드가 될 것입니다. ListRobotCommandS는 하나씩, 반복적으로 잠들고 설문 조사를하는 "Watcher"스레드 (확인 thingFound()). 만약에 thingFound() 그럼에도 불구하고 실행자 스레드뿐만 아니라 로봇을 멈출 수 있습니다. thingFound() 그렇다면 (필요한 경우) 신호를 보낼 수 있습니다.

분명히, 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 년경).

로봇은 조건 객체를 사용하여 컨트롤러에 일부 하위 작업이 완료되었거나 새 상태에 입력되었음을 신호를 보낼 수 있습니다.

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

흥미로운, 당신이있는 환경을 위해, 아마도 사용할 수 있고 notify () 그리고 기다리다() 보다 유연한 상태 대신. 로봇이 Notify ()로 그를 해제하기로 결정할 때까지 컨트롤러가 기다릴 수 있습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top