java thread: Thread.interrupt() not working

2019-08-08 22:03发布

I need to kill a thread that is not created in my code. In other words, the thread object is created by api (Eclipse JFace). Here is my code

ProgressMonitorDialog dialog = new ProgressMonitorDialog(null);
try {
        IRunnableWithProgress rp = new IRunnableWithProgress(){

            @Override
            public void run(IProgressMonitor monitor)
                    throws InvocationTargetException, InterruptedException {
                Thread.sleep(3000);

                Thread t = Thread.currentThread();
                t.getThreadGroup().list();

                t.interrupt();
            }
        };
        dialog.run(true, true, rp);
}
catch (Exception e) {
    e.printStackTrace();
}

Thread.currentThread() returns a thread with the name "ModalContext". Line t.getThreadGroup().list() returns the following data:

...
Thread[qtp1821431-38,5,main]
Thread[qtp1821431-39,5,main]
Thread[qtp1821431-40,5,main]
Thread[qtp1821431-42 Acceptor0 SelectChannelConnector@0.0.0.0:18080,5,main]
Thread[DestroyJavaVM,5,main]
Thread[ModalContext,5,main]

Variables "dialog" and "rp" do not have reference to their runnable object. And they don't have any method to close or cancel. So I want to kill that thread "ModalContext" directly. Calling t.interrupt() does not work. Thread MoadlContext continues to run. How can I kill the thread? Thanks

2条回答
时光不老,我们不散
2楼-- · 2019-08-08 22:07

t.interrupt() does not actually interrupt the thread immediately it only update interrupt status of thread. If your thread contains method which poll the interrupt status (i.e. sleep )only then the thread will be interrupted otherwise the thread simply complete the execution and interrupt status will be ignored.

Consider following example,

class RunMe implements Runnable {

    @Override
    public void run() {
        System.out.println("Executing :"+Thread.currentThread().getName());
        for(int i = 1; i <= 5; i++) {
            System.out.println("Inside loop for i = " +i);
        }
        System.out.println("Execution completed");
    }

}

public class Interrupted {

    public static void main(String[] args) {
        RunMe runMe = new RunMe();
        Thread t1 = new Thread(runMe);
        t1.start();
        t1.interrupt();//interrupt ignored
        System.out.println("Interrupt method called to interrupt t1");
    }
}

OUTPUT

Interrupt method called to interrupt t1
Executing :Thread-0
Inside loop for i = 1
Inside loop for i = 2
Inside loop for i = 3
Inside loop for i = 4
Inside loop for i = 5
Execution completed

Now just add Thread.sleep(200); in run and you will see the InterruptedException.

查看更多
SAY GOODBYE
3楼-- · 2019-08-08 22:20

The interrupt method doesn't kill the thread. It sets the "interrupted" status on the Thread, and if it's sleeping or waiting on I/O, then that method that it's calling will throw an InterruptedException.

However, you call interrupt on the current thread after sleep finishes, so this will do nothing but set the "interrupted" status.

You can do one of the following:

  1. Have another Thread call interrupt on that Thread. In run(), let the method complete if an InterruptedException is caught or if interrupted() returns true.
  2. Declare a volatile boolean variable (say, isRunning) that is initialized to true in the created thread. That thread will let the run() method complete if it's false. Have another Thread set it to false at the appropriate time.
查看更多
登录 后发表回答