2013-12-16 3 views
-4

Я следующий Java-код:Как сломать «а» цикл в Java, когда условие уложена

while(someMethod()) { 

    //do something 
} 

SomeMethod() разбирает текст с регулярным выражением. когда файл слишком большой, это может занять слишком много времени, и я предпочитаю его сломать. Как установить тайм-аут и разбить цикл, если someMethod() исчерпал время?

Спасибо!

P.S. важно: SomeMethod() не мой код, я не могу изменить его

+3

'SomeMethod()' должен возвращать логическое значение. Вы должны каким-то образом контролировать то, что оно возвращает. Без каких-либо подробностей мы не можем многое сделать. –

+0

он возвращает boolean, но когда он уложен, он ничего не возвращает. – sunny

+2

Что вы подразумеваете под «сложены»? Это не обычная терминология. –

ответ

0

Реализовать SomeMethod так, что она возвращает ложь, когда она достигает определенного предела:

boolean someMethod() { 
    long endTimeMillis = System.currentTimeMillis() + 10000; 
    while (true) { 
     // your code logic, you should also set yourChosenTimeoutInMillis here. 

     if (System.currentTimeMillis() > yourChosenTimeoutInMillis) { 
      return false; 
     } 
    } 
} 

С этим, ваше время будет выйти, если SomeMethod попадает в бесконечный цикл в его основной логике.

+0

nice, но someMethod() не мой код, я не могу его изменить ... – sunny

+0

Если это так, вы должны прибегать к потоковому использованию, которое я мог видеть, что другие уже предлагают. При однопоточном запуске вы не можете продолжать работу до тех пор, пока не будет выполнен некоторый метод. От этого не избежать. – Jops

0

Один из способов сделать это - создать новый поток, который вызывает этот метод, а затем вызвать Thread.join (long timeout) в вашем основном потоке.

public class ParserThread extends Thread 
    { 

    private volatile success = false 

    @Override 
    public void run() 
    { 
     success = someMethod(); 
    } 

    @Override 
    public void interrupt() 
    { 
     // TODO: try to cancel your logic here if possible to avoid wasted CPU cycles. 
    } 

    public boolean isSuccess() 
    { 
     return this.success; 
    } 
} 

В вашем основном классе:

ParserThread t = new ParserThread(); 
t.start(); 

t.join(5000); // Wait a maximum for 5 second for example 

if(t.isSuccess()) 
{ 
    // Do something if success 
} 
else 
{ 
    // Do something else if failure 
} 
+1

Расширение 'Thread' --- плохая идея. Переопределение «прерывания» - еще хуже. –

3

Вы должны включать в себя отдельный поток для вызова.

final ExecutorService executor = ...; 
final Callable<Boolean> someMethodCall = new Callable<>() { 
    @Override public boolean call() { return someMethod(); } 
}; 

while (executor.submit(someMethodCall).get(tmoutMillis, TimeUnit.MILLISECONDS)) 
{ 
    // whatever 
} 

Это будет блокировать для максимального срока, установленного и бросить TimeoutException oherwise, который будет вырваться из петли. Вы можете поймать исключение.

Обратите внимание, что это не очень элегантно, потому что вызов метода останется застрявшим и узурпирует эту ветку, возможно, навсегда. Нет безопасного пути вокруг этого, если метод не прерывается.

1

Полное применение, включая импорт:

package javaapplication4; 

import java.util.concurrent.Callable; 
import java.util.concurrent.ExecutionException; 
import java.util.concurrent.ExecutorService; 
import java.util.concurrent.Executors; 
import java.util.concurrent.Future; 
import java.util.concurrent.TimeUnit; 
import java.util.concurrent.TimeoutException; 
import java.util.concurrent.atomic.AtomicBoolean; 

public class JavaApplication4 { 

    private static final ExecutorService pool = Executors.newSingleThreadExecutor(); 

    private static boolean someMethod(long i) throws InterruptedException { 
     Thread.sleep(i*1000); 
     return true; 
    } 

    private static boolean someMethodTimeOut(long timeOut, final long i) throws InterruptedException, ExecutionException, TimeoutException { 
     Future<Boolean> res = pool.submit(new Callable<Boolean>(){ 
      @Override 
      public Boolean call() throws Exception { 
       return someMethod(i); 
      } 
     }); 

     return res.get(timeOut, TimeUnit.MILLISECONDS); 
    } 

    public static void main(String[] args) { 
     final long timeout = 5000; 
     long i = 0; 

     try { 
      while(someMethodTimeOut(timeout, i++)) { 
       System.out.println(i); 
      } 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      pool.shutdownNow(); 
     } 

    } 

} 
Смежные вопросы