views:

91

answers:

3

I have built a java application and have a thread thats doing something in the background when a button was pressed. The problem is, that thread might lock up, perhaps due to an infinite loop. Is there a way I can force terminate that thread?

EDIT: I am using LuaJ on the java platform. It has the potential of locking up and I don't really have much control over it apart from running it in another thread and killing it when either java or the script is finished.

+6  A: 

No, there is not. Your only choice without major witchcraft is to call interrupt() on it and wait for it to hit a blocking call. At that point, it will throw an InterruptedException which you should have terminate the thread.

If it is in a loop such as while(1); you can't really do much; you need to fix your thread to not do this, or to at least check a flag and stop itself.

For example, you could rewrite:

while(1) {
    doWork();
}

as:

class Whatever {
    private volatile boolean stop = false;
    ...
        while (!stop) {
            doALittleWork();
        }
    ...
}

There used to be a Thread.stop() method that does this but it is deprecated for very, very good reasons and should not be used.

EDIT: Since you're running presumably an interpreter, what you need to do is hook after every statement is executed (or so) and check your magic stop variable, and if so terminate Lua execution. Alternately, the Lua runtime may have its own "terminate" flag that you can use - I looked for documentation but their site is awful, so you may have to look at the code for this.

Beyond that, you may have to patch the Lua4j source manually to add this feature. Your options are pretty limited and ultimately the Thread has to somehow control its own fate.

Steven Schlansker
The problem is, this isn't java code locking things up. This is a scripting language that potential users of this software will be using. If they decide to write while(1); and then hit the stop button I need to be able to kill that thread.
Dave
+1 Great answer. Problems with threads getting caught in infinite loops are very difficult to deal with and cause big problems with thread management. They must be solved so that your threads never get in infinite loops. If the threads must be controlled from outside, you must put checks in intermittently to see if they should stop.
Erick Robertson
@Dave: between each line execution, can you have the thread check a run state variable, like @Steven's boolean stop variable, and exit the thread gracefully if it's set?
Erick Robertson
I would change the second `doWork()` to `doALittleWork()` to stress the idea that the work should be broken down into small work increments between which the stop flag is checked.
Bert F
@Erick: I have provided more detail in the description. I don't think I have the ability to do that.
Dave
A: 

Finally with the release of Java V5.0 (or V1.5), which incorporates java.util.concurrent, a definitive answer can be given. The answer is you stop a thread by using interrupt().

vaibhav
Yeah, Steven already said that as one of the options. It does no good if the thread doesn't execute code that would throw this exception, however.
Erick Robertson
Actually, `Thread.interrupt()` has always been there, and its semantics haven't changed a lot since the early days. As Steven pointed out this will not help if the thread does not perform any blocking wait or explicitly checks with `isInterrupted()`.
Grodriguez
A: 

What kind of scripts are the users writing? You could insert sleep or yield statements throughout their code (whether using Javassist or parsing the code) before you execute it. Then you could use interrupt to cancel the thread if it runs on too long. e A script is like any other form of user input, you need to sanitize it before you let it into your system where it can do damage. You can't guarantee how long it will run for but you should be able to add code to make sure you can cancel it.

Alternatively, this may be a case where it makes sense to kill the thread with stop(). The method is deprecated, but it has been that way since 1.2, and it's not going anywhere, because sometimes it's the only answer. You could let your users know they should check the current thread's interrupted flag or yield periodically so that their thread can get its affairs in order when you interrupt it, and also let them know that if they don't do this you reserve the right to kill the thread if it goes over a certain time.

Nathan Hughes
Where would I do that. At the moment it seems I can only do "dofile" and that just runs the script, no matter whats in there.
Dave
You would have to copy their script, modify the copy, then pass the copy to the command that runs it.
Nathan Hughes