7

If the method call takes more than 10 seconds I want to kill it and move on.

Is multi-threading my only option to solve this problem?

If I go with multi-threading which I'm very new at, my run method would only contain the one method as follows. If myMethod() gets stuck in an infinite loop is there a way to interrupt this thread?

public void run() {
    myMethod();
}

Let's assume myMethod() is the following and changing it is not an option.

while(true){
    System.out.println("Thinking.");
        for (int i = 0; i < 100000; i++) {
            //wasting time
        }
}

I was going for Mik378's solution, but I don't think this will work as myMethod doesn't throw the InterruptedException exception.

4

4 回答 4

7

Using threads to achieve this is tricky. There is no portable and safe method to kill a thread without cooperation from said thread. For further details, see How do you kill a thread in Java? and Why are Thread.stop [et al] deprecated?

A more robust approach is to call the method in the context of a separate process, and kill that process.

An even better approach is to understand why things are getting stuck in the first place, and figure out a way to prevent them from getting stuck (or a way to have a timeout and throw an exception etc). Whether that's a realistic possibility in your case, I don't know.

于 2012-12-06T16:47:55.180 回答
2

You can start a thread wrapped around your Runnable (named "thread"). Then do

thread.start();
thread.join(10000);
if (thread.isAlive()) {
  thread.interrupt();
}

As NPE mentioned, unless you are coding myMethod() yourself or know that it is sensitive to interruptions, there is no guarantee that this will actually kill the thread.

If you are implementing myMethod yourself, then what you need to do is have something like this inside the loop that method runs within the myMethod():

if (Thread.interrupted()) {
  break;  // or whatever you need to do to end the method quickly
}

I've left out exception handling. Your compiler will tell you what you need to do in that respect.

于 2012-12-06T17:14:36.927 回答
1

With two separated threads:

class Job implements Runnable {

        public void run(){
            try{
              myMethod();  // declared within this class or wherever you want
            } catch(InterruptedException){
                System.out.println("Interrupted now due probably to infinite loop !!");
            } 
        }

        public static void main(String[] args) throws InterruptedException {
           Job job = new Job();
           Thread process = new Thread(job);
           process.start(); 
           process.join(10000);  //wait here in order to detect wrong loop
           if(process.isAlive()){
             process.interrupt();
           }
        }
}
于 2012-12-06T17:15:59.613 回答
0

I agree with NPE, your best bet is to use multithreading with a separate process. That seems to be the safest way if you can't debug the method. Other options would be to simply use a timer and throw an exception if the timer exceeds 10 seconds. But that would be kind of unorthodox.

于 2012-12-06T16:57:05.887 回答