How can I kill a thread? without using stop();

2018-12-31 16:36发布

Thread currentThread=Thread.currentThread();
        public void run()
        {               

             while(!shutdown)
            {                               
                try
                {
                    System.out.println(currentThread.isAlive());
                Thread.interrupted();

                System.out.println(currentThread.isAlive());
                if(currentThread.isAlive()==false)
                {
                    shutdown=true;
                }
                }
                catch(Exception e)
                {
                    currentThread.interrupt();
                }                   
            }
        }

    });
    thread.start();

3条回答
路过你的时光
2楼-- · 2018-12-31 17:12

The alternative to calling stop is to use interrupt to signal to the thread that you want it to finish what it's doing. (This assumes the thread you want to stop is well-behaved, if it ignores InterruptedExceptions by eating them immediately after they are thrown and doesn't check the interrupted status then you are back to using stop().)

Here's some code I wrote as an answer to a threading question here, it's an example of how thread interruption works:

public class HelloWorld {

    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(new Runnable() {

            public void run() {
                try {
                    while (!Thread.currentThread().isInterrupted()) {
                        Thread.sleep(5000);
                        System.out.println("Hello World!");
                    }
                } catch (InterruptedException e) {
                    Thread.currentThread().interrupt();
                }
            }
        });
        thread.start();
        System.out.println("press enter to quit");
        System.in.read();
        thread.interrupt();
    }
}

Some things to be aware of:

  • Interrupting causes sleep() and wait() to immediately throw, otherwise you are stuck waiting for the sleep time to pass.

  • Note that there is no need for a separate boolean flag.

  • The thread being stopped cooperates by checking the interrupted status and catching InterruptedExceptions outside the while loop (using it to exit the loop). Interruption is one place where it's ok to use an exception for flow control, that is the whole point of it.

  • Setting interrupt on the current thread in the catch block is technically best-practice but is overkill for this example, because there is nothing else that needs the interrupt flag set.

Some observations about the posted code:

  • The posted example is incomplete, but putting a reference to the current thread in an instance variable seems like a bad idea. It will get initialized to whatever thread is creating the object, not to the thread executing the run method. If the same Runnable instance is executed on more than one thread then the instance variable won't reflect the right thread most of the time.

  • The check for whether the thread is alive is necessarily always going to result in true (unless there's an error where the currentThread instance variable is referencing the wrong thread), Thread#isAlive is false only after the thread has finished executing, it doesn't return false just because it's been interrupted.

  • Calling Thread#interrupted will result in clearing the interrupt flag, and makes no sense here, especially since the return value is discarded. The point of calling Thread#interrupted is to test the state of the interrupted flag and then clear it, it's a convenience method used by things that throw InterruptedException.

查看更多
笑指拈花
3楼-- · 2018-12-31 17:17

Good way to do it would be to use a boolean flag to signal the thread.

class MyRunnable implements Runnable {

    public volatile boolean stopThread = false;

    public void run() {
            while(!stopThread) {
                    // Thread code here
            }
    }

}

Create a MyRunnable instance called myrunnable, wrap it in a new Thread instance and start the instance. When you want to flag the thread to stop, set myrunnable.stopThread = true. This way, it doesn't get stopped in the middle of something, only where we expect it to get stopped.

查看更多
萌妹纸的霸气范
4楼-- · 2018-12-31 17:33

Typically, a thread is terminated when it's interrupted. So, why not use the native boolean? Try isInterrupted():

   Thread t = new Thread(new Runnable(){
        @Override
        public void run() {
            while(!Thread.currentThread().isInterrupted()){
                // do stuff         
            }   
        }});
    t.start();

    // Sleep a second, and then interrupt
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {}
    t.interrupt();
查看更多
登录 后发表回答