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
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
.
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:
- Have another
Thread
call interrupt
on that Thread
. In run()
, let the method complete if an InterruptedException
is caught or if interrupted()
returns true
.
- 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.