开发者

How to stop a thread that is running forever without any use

In the below code, i have a while(true) loop. considering a situation where there is some code in the try block where the thread is supposed to perform some tasks which takes about a minute, but due to some expected problem, it is running for ever. can we stop that thread ?


public class thread1 implements Runnable {

    /**
     * @param args
     */
    public static void main(String[] args) {
        // TODO Auto-generated method stub
        thread1 t1 =开发者_运维知识库 new thread1();
        t1.run();

    }

    @Override
    public void run() {
        // TODO Auto-generated method stub
        while(true){
            try{        
                Thread.sleep(10);

            }
            catch(Exception e){
                e.printStackTrace();
            }
        }
    }
}


First of all, you are not starting any thread here! You should create a new thread and pass your confusingly named thread1 Runnable to it:

thread1 t1 = new thread1();
final Thread thread = new Thread(t1);
thread.start();

Now, when you really have a thread, there is a built in feature to interrupt running threads, called... interrupt():

thread.interrupt();

However, setting this flag alone does nothing, you have to handle this in your running thread:

while(!Thread.currentThread().isInterrupted()){
    try{        
        Thread.sleep(10);
    }
    catch(InterruptedException e){
        Thread.currentThread().interrupt();
        break; //optional, since the while loop conditional should detect the interrupted state
    }
    catch(Exception e){
        e.printStackTrace();
    }

Two things to note: while loop will now end when thread isInterrupted(). But if the thread is interrupted during sleep, JVM is so kind it will inform you about by throwing InterruptedException out of sleep(). Catch it and break your loop. That's it!


As for other suggestions:

  • About Thread.stop():

Deprecated. This method is inherently unsafe[...]

  • Adding your own flag and keeping an eye on it is fine (just remember to use AtomicBoolean or volatile!), but why bother if JDK already provides you a built-in flag like this? The added benefit is interrupting sleeps, making thread interruption more responsive.


The proper way to stop a thread is to interrupt it (stop() is deprecated and may have nasty side effects):

t1.interrupt()

This will cause an InterruptedException to be thrown by methods like Thread.sleep() or Object.wait().

Then just add a catch block for this exception and simply break out of the while loop.

EDIT: I now realised that your infinite loop is running within the main thread, there's no thread created by your code, it's just run()ning a Runnable. You need to call Thread.start() at some point to spawn a new thread.


Move the catch interrupt to outside the loop. This doesn't require any more lines of code, it just handles interrupts correctly i.e. the action is interrupted.

public void run() {
    try{        
        while(true) {
            Thread.sleep(10);
        }
    } catch(InterruptedException e){
        System.out.println("Thread interrupted"));
    }
}


The only way to stop an arbitrary thread is by interrupting it. Keep a reference to it then call the interrupt method.


Create a field boolean keepGoing that you set to true before starting your thread and replace while (true) with while (keepGoing). At some point, you decide where, simply change the value of keepGoing to false and it will exit the loop.


I recommend using Thread.interrupt() (as mentioned by @Bohemian). It has a couple of advantages over using ad-hoc flags:

  • You don't need to create and use an application-specific API to do this. (And interrupts are guaranteed thread-safe ...)

  • Thread.interrupt() will interrupt threads that are blocked in a wait() or a join, or possibly1 some blocking I/O calls.

However, it is not a magic bullet. If the thread you are trying to stop is executing regular code, it needs to periodically check its interrupted() flag, or it won't no to stop. This leaves us in the same as boat as we are in with an ad-hoc flag mechanism. The thread has to cooperate, or it can't be (safely) stopped.

1 - This is a murky area. On the one hand, there is an InterruptedIOException whose javadoc says "Signals that an I/O operation has been interrupted". On the other hand, the exception is not explicitly mentioned in the javadocs for the various java.io stream classes.


It is true that some 3rd-party code may not deal with the interrupted flag properly, and interrupts may get "eaten" as a result. But you can check for that if you have source code. And the situation is not a lot different to the 3rd-party code not paying attention to your ad-hoc flag mechanism.


I would NOT recommend using Thread.stop(). It is fundamentally flakey. Some people claim that it works for them, but IMO they are either dealing with a special case that works ... or they are being lucky.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜