简体   繁体   English

杀死Java中的无限循环

[英]killing an infinite loop in java

I am using a third-party library to process a large number of data sets. 我正在使用第三方库来处理大量数据集。 The process very occasionally goes into an infinite loop (or is blocked - don't know why and can't get into the code). 该过程有时会陷入无限循环(或被阻塞-不知道为什么并且无法进入代码)。 I'd like to kill this after a set time and continue to the next case. 我想在设定的时间后消除这个问题,然后继续处理下一个案件。 A simple example is: 一个简单的例子是:

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

processData normally takes 1 second max. processData通常最多需要1秒。 I'd like to set a timer which kills processData() after , say, 10 seconds 我想设置一个计时器,该计时器在10秒后杀死processData()

EDIT I would appreciate a code snippet (I am not practiced in using Threads). 编辑我将不胜感激一个代码片段(我没有在使用Thread的过程中练习过)。 The Executor approach looks useful but I don't quite know how to start. 执行器方法看起来很有用,但我不太知道如何开始。 Also the pseudocode for the more conventional approach is too general for me to code. 同样,对于更常规的方法而言,伪代码对我来说太通用了。

@Steven Schlansker - suggests that unless the thirdparty app anticipates the interrupt it won't work. @Steven Schlansker-建议除非第三方应用程序预期中断,否则它将无法正常工作。 Again detail and examples would be appreciated 再次详细和示例将不胜感激

EDIT I got the precise solution I was wanting from my colleagues Sam Adams, which I am appending as an answer. 编辑我的同事Sam Adams得到了我想要的精确解决方案,我将其作为答案附在后面。 It has more detail than the other answers, but I will give them both a vote. 它比其他答案更详细,但是我将给他们两个投票。 I'll mark Sam's as the approved answer 我将Sam标记为已批准答案

One of the ExecutorService.invokeAll(...) methods takes a timeout argument. ExecutorService.invokeAll(...)方法之一采用超时参数。 Create a single Callable that calls the library, and wrap it in a List as an argument to that method. 创建一个调用该库的Callable,并将其包装在List中作为该方法的参数。 The Future returned indicate how it went. 返回的未来表明了它的发展情况。

(Note: untested by me) (注:未经我测试)

Put the call to the library in another thread and kill this thread after a timeout. 将对库的调用放在另一个线程中,并在超时后终止该线程。 That way you could also proces multiple objects at the same time if they are not dependant to each other. 这样,如果它们彼此不依赖,您也可以同时处理多个对象。


EDIT: Democode request 编辑:演示代码请求

This is pseudo code so you have to improve and extend it. 这是伪代码,因此您必须对其进行改进和扩展。 Also error checking weather a call was succesful or not will be of help. 另外,如果检查呼叫成功与否,则进行错误检查将有所帮助。

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

Sam Adams sent me the following answer, which is my accepted one 萨姆·亚当斯(Sam Adams)向我发送了以下答案,这是我接受的答案

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

and myRunnableCode regularly checks Thread.isInterrupted() , and exits cleanly if this returns true. myRunnableCode定期检查Thread.isInterrupted() ,如果返回true则干净地退出。

Alternatively you can do: 或者,您可以执行以下操作:

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

But this method has been deprecated since it is DANGEROUS. 但是由于危险,因此不推荐使用此方法。

http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html#stop() "This method is inherently unsafe. Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior." http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html#stop() “此方法本质上是不安全的。使用Thread.stop停止线程会导致其解锁所有它已锁定的监视器的数量(由于未经检查的ThreadDeath异常正在堆栈中传播),如果以前受这些监视器保护的任何对象处于不一致状态,则损坏的对象将对其他线程可见,可能导致以任意行为。”

I've implemented the second and it does what I want at present. 我已经实现了第二个,它可以满足我目前的需求。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM