问题
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
回答1:
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
.
回答2:
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
callinterrupt
on thatThread
. Inrun()
, let the method complete if anInterruptedException
is caught or if interrupted() returnstrue
. - Declare a
volatile boolean
variable (say,isRunning
) that is initialized totrue
in the created thread. That thread will let therun()
method complete if it'sfalse
. Have anotherThread
set it tofalse
at the appropriate time.
来源:https://stackoverflow.com/questions/32486717/java-thread-thread-interrupt-not-working