java thread: Thread.interrupt() not working - java

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

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.

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.

Related

Two thread which invokes wait and notify

The code I've witten doesn't work as I expected.
static Integer sync = 1;
static void m() throws Exception {
synchronized (sync) {
System.err.println("First");
sync.notify();
sync.wait(1000L);
System.err.println("Second");
System.err.println("Third");
}
}
public static void main(String[] args) throws Exception {
Runnable r = new Runnable() {
#Override
public void run() {
try {
m();
} catch (Exception ex) {
Logger.getLogger(IO.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
Runnable t = new Runnable() {
#Override
public void run() {
try {
m();
} catch (Exception ex) {
Logger.getLogger(IO.class.getName()).log(Level.SEVERE, null, ex);
}
}
};
Thread th1 = new Thread(r);
Thread th2 = new Thread(t);
th1.run();
th2.run();
}
We have two threads which execute m()'s syncjronized statement. When the first thread executes one and come across the wait() it'll be added to the wait set. After this, the second thread is starting to execute the synchronized statement, and perform notify(). Since the output must be
First
First
....
But actually it is
First
Second
Third
First
Second
Third
Why?
First of all, your program is not creating any threads. You must call th1.start() and th2.start() to create threads.
t.start() is the method that the library provides for your code to call when you want to start a thread. run() is the method that you provide for the library to call in the new thread. Your run() method defines what the thread will do. IMO, run() was a really misleading name.
Second, notify() and wait() don't do what it looks like you think they will do. In particular, sync.notify() will not do anything at all if there are no other threads currently in sync.wait().
The correct way to use notify() and wait() is, one thread does this:
synchronized(lock) {
while (! someCondition()) {
lock.wait()
}
doSomethingThatRequiresSomeConditionToBeTrue();
}
The other thread does this
synchronized(lock) {
doSomethingThatMakesSomeConditionTrue();
lock.notify();
}
When you use this pattern, no thread should ever change the result of someCondition() except from inside a synchronized(lock) block.
Firstly, To actually create new threads please use
th1.start()
th2.start()
inplace of run() , which is just a regular method call on the thread object.
Secondly, it is possible that the second thread 'th2' did not start running by the time 1000 ms was fninshed , so the first thread finished wait(1000) and executed the remainging lines of code.
if you want the output like so :
first
first
second
third
second
third
then remove the time interval for wait() which will make the threads wait until notified.
as in :
static void m() throws Exception {
synchronized (sync) {
System.err.println("First");
sync.notify();
sync.wait();
System.err.println("Second");
System.err.println("Third");
}
}
Use .start() instead of run() to add runables to the queue instead of running them immediately
Documentation says that wait with timeout waits for any notify on this object or the timeout. In your case when runnables are being executed one by one it goes:
r: First
r: waits 1000ms and try to get lock
r: it already have access to lock object (exactly this code got lock) so continue
r: Second
r: Third
t: First, and so on ...
PS. calling run() and not setting timeout will cause deadlock on t's wait, cause it already has the object but will wait never be notified about it.
Hope this helps.

Sleep inner thread without sleeping outer thread - Java

I have a main Mina handler thread is processing and in that thread i made another thread and set it to sleep for specified time. Now i want that this inner thread sleep independently without blocking Handler thread.
following is sample code.
public void messageReceived(IoSession session, Object message) throws Exception {
Integer tts = 5000;
Thread sleepThread = new Thread(obj);
sleepThread.sleep(tts);
}
currently it is blocking main Handler thread.
Thread.sleep() is a static method, so calling sleepThread.sleep(tts) is the same as Thread.sleep(tts). Hence your current thread is just sleeping.
You can't cause another thread to sleep by calling a method on its Thread object. At a push, you could set a flag on the object and your thread could check for the presence of that flag and behave accordingly.
try
final int tts = 5000;
Thread sleepThread = new Thread() {
public void run() {
try {
Thread.sleep(tts);
} catch (InterruptedException e) {
throw new RuntimeException(e);
}
}
};
sleepThread.start();

Why was task1 thread not interrupted

Assume the below code is executed with a debugger so that we can predict the order of execution.
t1 -- Here task1 starts working on some long task.
t2 --- task2 gets blocked # Syncronized statement because task1 is holding lock.
t3 -- task2 is interrupted but its missed because task2 is using intrinsic locks and hence cannot be interrupted # synchronized. (Renenterant.lockInterruptible() would have thrown InterruptedExecption).
t4 --- task1 is interrupted. However despite of doing the complex task in try catch block, InterruptedExecption was never thrown. Why is that ?
Code:
public class TestInteruptibility {
public static Object lock = new Object();
public static boolean spin = true;
public static void main(String[] args) {
Thread task1 = new Thread(new Task(), "Task1");
Thread task2 = new Thread(new Task(), "Task2");
Thread notifier1 = new Thread(new Notifier(), "Notifier1");
task1.start();
task2.start();
task2.interrupt();
task1.interrupt();
notifier1.start();
}
}
class Task implements Runnable {
public void run() {
synchronized (TestInteruptibility.lock) {
System.out.println("Performing Long Task");
try {
while (TestInteruptibility.spin) {
}
System.out.println("Finsihed Performing Long Task");
TestInteruptibility.lock.wait();
} catch (InterruptedException e) {
e.printStackTrace();
System.out.println("I got interrupted while i was waiting # wait()");
}
System.out.println("Ending Task");
}
}
}
class Notifier implements Runnable {
public void run() {
synchronized (TestInteruptibility.lock) {
System.out.println("Performing notification");
TestInteruptibility.lock.notify();
System.out.println("Ending notification");
}
}
}
Basically, what interrupt() does is to set a flag in the Thread object. And you need to check it with isInterrupted(). Then you can handle this interrupt signal. It won't throw an InterruptedException in this situation.
Besides, it can cause some methods, for example, Thread.sleep(), Object.wait(), to return immediately and throw an InterruptedException. And you can get and InterruptedException in this situation.
From Java Concurrency in Practice, 7.1.1. Interruption:
A good way to think about interruption is that it does not actually interrupt a running thread; it just requests that the thread interrupt itself at the next convenient opportunity. (These opportunities are called cancellation points.) Some methods, such as wait, sleep, and join, take such requests seriously, throwing an exception when they receive an interrupt request or encounter an already set interrupt status upon entry. Well behaved methods may totally ignore such requests so long as they leave the interruption request in place so that calling code can do something with it. Poorly behaved methods swallow the interrupt request, thus denying code further up the call stack the opportunity to act on it.
In your above code, you are not waiting/sleeping. So you have to check isInterrupted() and handle interrupt signal yourself in the while loop.
while (TestInteruptibility.spin) {
if (Thread.currentThread().isInterrupted()) {
break;
}
}
References:
why interrupt() not work as expected and how does it work
What does java.lang.Thread.interrupt() do?
You have a busy while loop, that holds the lock (and never ends, unless you change spin's value somewhere). I suppose that task1 is still in the loop, therefore it doesn't notice the interruption. Task2 can't acquire the lock, so it blocks.
The way Task is implemented, it can only be interrupted in during the wait command, which comes after the loop.
BTW: if you are using the spin data member in different threads, then it should probably be declared as volatile. For similar thread safety reasons, lock should be declared as final.
When you call method interrupt() the result depends on the this thread is doing currently. If it is blocked on some interruptable method such as Object.wait(), then it will be interrupted immediately, which means that InterruptedException will be throw inside the thread. If thread is not blocked, but is doing some calculations, or it is block on some non-interruptable method such as InputStream.read() then InterruptedException is not thrown, but interrupted flag is set on thread instead. This flag will cause InterruptedException next time thread will call some interruptable method, but not now.
In your case threads task1 and task2 are spinning in infinite empty loops and thus are not blocked on any interruptable methods, so when you call interrupt() on then, no InterruptedException is thrown inside that threads, but interrupted flag is just set. You probably should change your task code to look like this:
while (TestInteruptibility.spin && !Thread.interrupted ()) {
}
then you will exit from the loop as long as somebody will call interrupt on task thread.

Stop thread and again start giving IllegalThreadStateException in blackberry

I am getting IllegalThreadStateException exception when using following code:
I have already started this thread once(by using thread.start()) and again trying to start it at another place, so used following code:
thread.interrupt();
thread.start();
But thread.start() is throwing IllegalThreadStateException.
What should I use to solve it?
Thread objects are only meant to be started once. If you need to stop/interrupt a Thread, and then want to start it again, you should create a new instance, and call start() on it:
thread.interrupt(); // if you need to make sure thread's run() method stops ASAP
thread = new MyThreadSubclass();
thread.start();
From the API docs
IllegalThreadStateException - if the thread was already started.
I know it's not 100% clear that you can't call start() again, even if you previously called interrupt(), but that's the way it works.
If you look at the API docs for standard Java, this issue is more clear.
In addition to Nate's answer.
AnkitRox states in his comment:
Thanks Nate. I was also trying your method. But the problem occurred at that time was, it was start a new thread for the new instance and previous thread was also working.
So it looks like the problem is "the thread is still running even if I called interrupt on it". Consider this sample (it is ugly, but enough to show the main idea):
final Thread t = new Thread(new Runnable() {
public void run() {
while (true) {
for (int i = 0; i < 100000000; i++); // simulate some action
System.out.println("hi, interrupted = "
+ Thread.currentThread().isInterrupted());
}
}
});
t.start();
new Timer(true).schedule(
new TimerTask() {
public void run() {
t.interrupt();
}
},
1000 // 1 second delay
);
Note, the thread continues to run even after interrupt() has been called. The produced output is:
hi, interrupted = false
hi, interrupted = true
hi, interrupted = true
hi, interrupted = true
...
hi, interrupted = true
Actually the programm never stops unless closed forcefully. So what then the interrupt() does? It just sets the interrupted flag to true. After interrupt() has been called the Thread.currentThread().isInterrupted() starts to return false. And that's all.
Another case is if interrupt() is called while the thread is blocked in an invocation of one of the methods that throw InterruptedException, then that method will return throwing the InterruptedException. And if thread's code just "eats" that exception, then the thread will still continue running, consider a sample:
final Thread t = new Thread(new Runnable() {
public void run() {
while (true) {
System.out.println("hi, interrupted = "
+ Thread.currentThread().isInterrupted());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("got InterruptedException");
}
}
}
});
t.start();
new Timer(true).schedule(
new TimerTask() {
public void run() {
t.interrupt();
}
},
1000 // 1 second delay
);
Note, the thread continues to run even after interrupt() has been called. The produced output is:
hi, interrupted = false
got InterruptedException
hi, interrupted = false
hi, interrupted = false
...
hi, interrupted = false
Note, this time interrupted = false even after interrupt() has been called. This is because whenever InterruptedException is caught, the interrupted flag is reset to false.
In Java stopping a thread is cooperative mechanism. Meaning it can not be done without cooperation from the thread itself. Here is the fixed version of the above sample:
final Thread t = new Thread(new Runnable() {
public void run() {
while (!Thread.currentThread().isInterrupted()) {
System.out.println("hi, interrupted = "
+ Thread.currentThread().isInterrupted());
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
System.out.println("we've been interrupted");
// restore the interrupted flag
Thread.currentThread().interrupt();
}
}
}
});
t.start();
new Timer(true).schedule(
new TimerTask() {
public void run() {
t.interrupt();
}
},
1000 // 1 second delay
);
So the correct approach should be to periodically check the interrupted flag. And if interrupted status is detected then just return ASAP. Another common option is not to use Thread.interrupt() at all, but some custom boolean instead.

Java wait()/join(): Why does this not deadlock?

Given the following Java code:
public class Test {
static private class MyThread extends Thread {
private boolean mustShutdown = false;
#Override
public synchronized void run() {
// loop and do nothing, just wait until we must shut down
while (!mustShutdown) {
try {
wait();
} catch (InterruptedException e) {
System.out.println("Exception on wait()");
}
}
}
public synchronized void shutdown() throws InterruptedException {
// set flag for termination, notify the thread and wait for it to die
mustShutdown = true;
notify();
join(); // lock still being held here, due to 'synchronized'
}
}
public static void main(String[] args) {
MyThread mt = new MyThread();
mt.start();
try {
Thread.sleep(1000);
mt.shutdown();
} catch (InterruptedException e) {
System.out.println("Exception in main()");
}
}
}
Running this will wait for one second and then properly exit. But that is unexpected to me, I expect a dead-lock to happen here.
My reasoning is as follows: The newly created MyThread will execute run(), which is declared as 'synchronized', so that it may call wait() and safely read 'mustShutdown'; during that wait() call, the lock is released and re-acquired upon returning, as described in the documentation of wait(). After one second, the main thread executes shutdown(), which is again synchronized as to not access mustShutdown at the same time as it's being read by the other thread. It then wakes up the other thread via notify() and the waits for its completion via join().
But in my opinion, there's no way that the other thread can ever return from wait(), since it needs to re-acquire the lock on the thread object before returning. It cannot do so because shutdown() still holds the lock while inside join(). Why does it still work and exit properly?
join() method internally calls wait() which will result in releasing of the lock(of Thread object).
See the code of join() below:
public final synchronized void join(long millis)
throws InterruptedException {
....
if (millis == 0) {
while (isAlive()) {
wait(0); //ends up releasing lock
}
}
....
}
Reason why your code sees this and not seen in general:: The reason why your code see this and not is not observed in general, is because the join() method waits() on Thread object itself and consequently relinquishes lock on the Thread object itself and as your run() method also synchronizes on the same Thread object, you see this otherwise unexpected scenario.
The implementation of Thread.join uses wait, which lets go of its lock, which is why it doesn't prevent the other thread from acquiring the lock.
Here is a step-by-step description of what happens in this example:
Starting the MyThread thread in the main method results in a new thread executing the MyThread run method. The main Thread sleeps for a whole second, giving the new Thread plenty of time to start up and acquire the lock on the MyThread object.
The new thread can then enter the wait method and release its lock. At this point the new thread goes dormant, it won't try to acquire the lock again until it is woken up. The thread does not return from the wait method yet.
At this point the main thread wakes up from sleeping and calls shutdown on the MyThread object. It has no problem acquiring the lock because the new thread released it once it started waiting. The main thread calls notify now. Entering the join method, the main thread checks that the new thread is still alive, then waits, releasing the lock.
The notification happens once the main thread releases the lock. Since the new thread was in the wait set for the lock at the time the main thread called notify, the new thread receives the notification and wakes up. It can acquire the lock, leave the wait method, and finish executing the run method, finally releasing the lock.
The termination of the new thread causes all threads waiting on its lock to receive a notification. This wakes up the main thread, it can acquire the lock and check that the new thread is dead, then it will exit the join method and finish executing.
/**
* Waits at most <code>millis</code> milliseconds for this thread to
* die. A timeout of <code>0</code> means to wait forever.
*
* #param millis the time to wait in milliseconds.
* #exception InterruptedException if any thread has interrupted
* the current thread. The <i>interrupted status</i> of the
* current thread is cleared when this exception is thrown.
*/
public final synchronized void join(long millis)
throws InterruptedException {
long base = System.currentTimeMillis();
long now = 0;
if (millis < 0) {
throw new IllegalArgumentException("timeout value is negative");
}
if (millis == 0) {
while (isAlive()) {
wait(0);
}
} else {
while (isAlive()) {
long delay = millis - now;
if (delay <= 0) {
break;
}
wait(delay);
now = System.currentTimeMillis() - base;
}
}
}
To complement the other answers: I see no mention of join() releasing any locks in the API-documentation, so this behavior is actually implementation-specific.
Learn from this:
don't subclass Thread, instead use a Runnable implementation passed to your thread object.
don't synchronize/wait/notify on objects you don't "own", e.g. where you don't know who else might synchronize/wait/notify on it.

Categories