代码之家  ›  专栏  ›  技术社区  ›  peter.murray.rust

在java中终止无限循环

  •  5
  • peter.murray.rust  · 技术社区  · 14 年前

    我正在使用第三方库来处理大量的数据集。这个过程偶尔会进入一个无限循环(或者被阻塞——不知道为什么,无法进入代码)。我想在一段时间后结束这件事,继续下一个案子。一个简单的例子是:

    for (Object data : dataList) {
        Object result = TheirLibrary.processData(data);
        store(result);
    }
    

    编辑

    @史蒂文施兰斯克-建议,除非第三方应用程序预期的中断,它不会工作。同样的细节和例子将不胜感激

    编辑 我从我的同事萨姆·亚当斯那里得到了我想要的精确解决方案,我把它作为一个答案附在后面。它比其他答案更详细,但我会给他们两个投票。我会把萨姆的答案记下来

    3 回复  |  直到 14 年前
        1
  •  10
  •   Greg Hewgill    14 年前

    其中一个 ExecutorService.invokeAll(...) 方法接受超时参数。创建一个调用库的可调用函数,并将其作为该方法的参数包装在列表中。返回的未来表明了它是如何发展的。

        2
  •  7
  •   schoetbi    14 年前

    将对库的调用放在另一个线程中,并在超时后终止此线程。这样,如果多个对象彼此不依赖,也可以同时处理它们。


    这是伪代码,所以您必须改进和扩展它。此外,检查呼叫是否成功也会有帮助。

    for (Object data : dataList) {
        Thread t = new LibThread(data);
        // store the thread somewhere with an id
        // tid and starting time tstart 
        // threads
        t.start();
        }
    
    while(!all threads finished)
    {
        for (Thread t : threads)
        {
            // get start time of thread
            // and check the timeout
            if (runtime > timeout)
            {
                t.stop();
            }
        }
    }
    
    class LibThread extends Thread {
        Object data;
    
        public TextThread(Object data) 
        {
            this.data = data;
        }
    
        public void processData() 
        {
            Object result = TheirLibrary.processData(data);
            store(result);
        }
    }
    
        3
  •  2
  •   peter.murray.rust    14 年前

    Thread thread = new Thread(myRunnableCode);
    thread.start();
    thread.join(timeoutMs);
    if (thread.isAlive()) {
      thread.interrupt();
    }
    

    myRunnableCode Thread.isInterrupted() ,如果返回true,则干净地退出。

    或者,您可以:

    Thread thread = new Thread(myRunnableCode);
    thread.start();
    thread.join(timeoutMs);
    if (thread.isAlive()) {
      thread.stop();
    }
    

    http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html#stop() “这种方法本身就不安全。停止线程Thread.stop 使它解锁它已锁定的所有监视器(这是未检查的ThreadDeath异常向堆栈上传播的自然结果)。如果以前受这些监视器保护的任何对象处于不一致的状态,则损坏的对象将对其他线程可见,从而可能导致任意行为。”