Java에서 일련의 절차를 방해하려면 어떻게해야합니까?
-
19-09-2019 - |
문제
나는 모두 실행되거나 특정 조건이 충족 될 때까지 연속적으로 실행 해야하는 많은 절차가 있습니다. 조건이 충족 될 때까지 실행 해야하는 기본 코드는 다음과 같습니다.
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로 List
의 RobotCommand
, 방법이 있습니다 executeRobotAlgorithm
목록 위에 반복되어 전화를 걸었습니다 execute
각각에 RobotCommand
그리고 결과를 확인합니다 thingFound()
각각 후.
편집하다 - 오, 내가 얻는 것 같아요. 하다 go
그리고 spin
로봇의 상태를 바꾸는 스레드를 시작하십시오.
편집 2 - 귀하의 의견에 대한 응답으로, 여기서 문제는 로봇이 찾고있는 것을 찾으면 즉시 반환 할 수 있어야한다는 것입니다. go
, spin
, ETC 명령은 지금이 작업을 수행하지 않으며 그 동안 새로운 명령을 계속 실행할 수있는 기능이 필요합니다. 그래서 내가 여기서 할 수있는 것은 두 개의 스레드가 있습니다. 하나는 당신을 실행할 "집행자"스레드가 될 것입니다. List
의 RobotCommand
S는 하나씩, 반복적으로 잠들고 설문 조사를하는 "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 ()로 그를 해제하기로 결정할 때까지 컨트롤러가 기다릴 수 있습니다.