有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

当条件被叠加时,如何在Java中中断“while”循环

我有以下Java代码:

while( someMethod() )   {

   //do something
}

someMethod()使用正则表达式解析某些文本。当文件太大时,可能会花费太多时间,我更喜欢将其破坏。 如果someMethod()耗尽了时间,我如何设置超时并中断循环

谢谢大家!

重要提示:someMethod()不是我的代码,我无法更改它


共 (4) 个答案

  1. # 1 楼答案

    一种方法是创建一个调用该方法的新线程,然后调用线程。在主线程中加入(长超时)

     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
    }
    
  2. # 2 楼答案

    您必须为该调用包含一个单独的线程

    final ExecutorService executor = ...;
    final Callable<Boolean> someMethodCall = new Callable<>() {
        @Override public boolean call() { return someMethod(); }
    };
    
    while (executor.submit(someMethodCall).get(tmoutMillis, TimeUnit.MILLISECONDS))
    {
        // whatever
    }
    

    这将在指定的最长时间段内阻塞,并抛出一个TimeoutExceptionoherwise,这将中断循环。您可以捕获异常

    请注意,这并不是很优雅,因为对该方法的调用将保持不变,并可能永远占用该线程。如果方法不可中断,就没有安全的解决方法

  3. # 3 楼答案

    实现someMethod,使其在达到指定限制时返回false:

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

    这样,如果某个方法在其核心逻辑中陷入无限循环,那么while将退出

  4. # 4 楼答案

    完整的应用程序包括导入:

    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();
            }
    
        }
    
    }