2010-11-23 12 views
18

코드에서 변수 타이머는 while 루프를 끝내기까지의 지속 시간을 지정합니다 (예 : 60 초).Java에서 일정 시간이 지나면 실행을 중지하는 방법은 무엇입니까?

while(timer) { 
    //run 
    //terminate after 60 sec 
    } 
+1

우리가 여기 오래된 스레드를 다시 해싱있어 보인다 : HTTP : // WWW http://stackoverflow.com/questions/2550536/java-loop-for-a-certain-duration – Dmitri

+0

이 문서를 확인하십시오. yegor256.com/2014/06/20/limit-method-execution-time.html – yegor256

+0

[스레드를 시간 종료하는 방법] 가능한 복제본 (http://stackoverflow.com/questions/2275443/how-to-timeout-a -thread) – vhunsicker

답변

38
long start = System.currentTimeMillis(); 
long end = start + 60*1000; // 60 seconds * 1000 ms/sec 
while (System.currentTimeMillis() < end) 
{ 
    // run 
} 
+8

하지만 59 초에 시작할 때 루프의 반복이 시작되고 루프의 각 반복에 1 초 이상이 걸리면 60 초 이상 걸리십니까? 할 수있는 최선의 방법인가요? 나는 순수한 무지에서 벗어나고있다. – Ramy

+0

@Ramy : 아니요. '시작'과 '종료'는 절대 시간이며, 신기원 (자정, 1970 년 1 월 1 일 자정) 이래로 밀리 초 단위로 측정됩니다. 롤오버가 없습니다. –

+6

괜찮지 만 루프의 시작 부분에서만 검사가 수행됩니다. 따라서 루프의 시작 부분에서 59 초가 경과했다면 루프의 각 반복에는 5 초가 걸립니다. 다음 번 while 루프가 점검되면 64 초가 경과합니다. 맞지, 내가 놓친 게 있니? – Ramy

1

는 while 루프가 무엇을하고 있는지에 따라 다릅니다. 장시간 차단 될 가능성이있는 경우 TimerTask을 사용하여 stopExecution 플래그를 설정하고 작업을 예약하고 .interrupt() 스레드를 설정하십시오.

루프의 시간 조건만으로는 입력 또는 잠금을 영원히 기다릴 수 있습니다 (그러면 다시 문제가되지 않을 수도 있음).

3

시간 제한을 초과 할 수 없다면 (하드 한도) 스레드가 가장 좋습니다. 루프를 사용하여 시간 임계 값에 도달하면 스레드를 종료 할 수 있습니다. 그 시점에서 그 스레드에서 진행중인 모든 작업이 중단되어 거의 즉시 계산을 중지 할 수 있습니다. 예를 들면 다음과 같습니다.

Thread t = new Thread(myRunnable); // myRunnable does your calculations 

long startTime = System.currentTimeMillis(); 
long endTime = startTime + 60000L; 

t.start(); // Kick off calculations 

while (System.currentTimeMillis() < endTime) { 
    // Still within time theshold, wait a little longer 
    try { 
     Thread.sleep(500L); // Sleep 1/2 second 
    } catch (InterruptedException e) { 
     // Someone woke us up during sleep, that's OK 
    } 
} 

t.interrupt(); // Tell the thread to stop 
t.join();  // Wait for the thread to cleanup and finish 

약 1/2 초의 해상도를 제공합니다. while 루프에서 더 자주 폴링하면이를 알 수 있습니다.

귀하의 실행 가능한의 실행은 다음과 같이 보일 것입니다 :

public void run() { 
    while (true) { 
     try { 
      // Long running work 
      calculateMassOfUniverse(); 
     } catch (InterruptedException e) { 
      // We were signaled, clean things up 
      cleanupStuff(); 
      break;   // Leave the loop, thread will exit 
    } 
} 

업데이트 드미트리 당신이 루프를 방지 할 것 TimerTask을 지적 드미트리의 대답

에 따라. 당신은 join 호출을 할 수 있으며 당신이 설정 한 TimerTask는 쓰레드를 방해 할 것입니다. 이렇게하면 루프에서 폴링하지 않고도 더 정확한 해상도를 얻을 수 있습니다.

+0

그런데'.interrupt()'가 작동하는 방식이 아닙니다. 쓰레드가 막히지 않는 한,'interrupted' 플래그를 설정하기 만하면 쓰레드는 실행을 멈추기 위해서 그것을 체크해야한다. 또한,'InterruptedException'는 검사 된 예외이며, 임의의 코드 주위에 던져 넣을 수 없습니다 (예제는 컴파일되지 않습니다). – Dmitri

17

새 Java Executor 서비스를 사용해보십시오. http://docs.oracle.com/javase/6/docs/api/java/util/concurrent/ExecutorService.html

이렇게하면 스스로 측정 시간을 프로그래밍 할 필요가 없습니다.

public class Starter { 

    public static void main(final String[] args) { 
     final ExecutorService service = Executors.newSingleThreadExecutor(); 

     try { 
      final Future<Object> f = service.submit(() -> { 
       // Do you long running calculation here 
       Thread.sleep(1337); // Simulate some delay 
       return "42"; 
      }); 

      System.out.println(f.get(1, TimeUnit.SECONDS)); 
     } catch (final TimeoutException e) { 
      System.err.println("Calculation took to long"); 
     } catch (final Exception e) { 
      throw new RuntimeException(e); 
     } finally { 
      service.shutdown(); 
     } 
    } 
} 
+0

여기에 설정 한 시간 초과 값은 무엇입니까? – nikk

+0

"제한 시간"이란 무엇입니까? 'Thread.sleep (1337); – Murmel

+0

나는 "timeout"으로 믿는다. @nikk은 서비스가 종료 된 후의 시간을 의미한다. – lostsoul29

관련 문제