interrupt() not working as expected (how does interrupt work?) - java

I want to interrupt a thread, but invoking interrupt() doesn't seem to work. Below is the sample code:
public class BasicThreadrRunner {
public static void main(String[] args) {
Thread t1 = new Thread(new Basic(), "thread1");
t1.start();
Thread t3 = new Thread(new Basic(), "thread3");
Thread t4 = new Thread(new Basic(), "thread4");
t3.start();
t1.interrupt();
t4.start();
}
}
class Basic implements Runnable{
public void run(){
while(true) {
System.out.println(Thread.currentThread().getName());
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
System.err.println("thread: " + Thread.currentThread().getName());
//e.printStackTrace();
}
}
}
}
but the output looks like thread 1 is still running. Can anyone explain this as well as how interrupt() works? Thanks!

The thread is still running simply because you catch InterruptedException and keep running. interrupt() primarily sets a flag in the Thread object, which you can check with isInterrupted(). It also causes some methods -- sleep(), join Object.wait(), in particular -- to return immediately by throwing an InterruptedException. It also causes some I/O operations to immediately terminate. If you're seeing the printouts from your catch block, then you can see that interrupt() is working.

As others have said, you catch the interrupt, but do nothing with it. What you need to do is propagate the interrupt using logic such as,
while(!Thread.currentThread().isInterrupted()){
try{
// do stuff
}catch(InterruptedException e){
Thread.currentThread().interrupt(); // propagate interrupt
}
}
Using looping logic, such as while(true) is just lazy coding. Instead, poll the thread's interrupted flag in order to determine termination via interruption.

++1, in addition to other answers. I believe the misconception about this was that it seemed the try/catch block finished its job after the Thread.sleep(1000); call i.e. try to sleep for 1000ms, catch anything that might interrupt my sleep attempt.
What is happening actually is that the try/catch block is still very much active while sleeping i.e. try to sleep for 1000ms, catch anything that might interrupt during my sleep
Hence the reason why the exception is being caught immediately (and afterwards) since the thread barely just started its sleep.

Related

Polling empty queue - JCIP listing 7.7

In this code
public class NoncancelableTask {
public Task getNextTask(BlockingQueue<Task> queue) {
boolean interrupted = false;
try {
while (true) {
try {
return queue.take();
} catch (InterruptedException e) {
interrupted = true;
// fall through and retry
}
}
} finally {
if (interrupted)
Thread.currentThread().interrupt();
}
}
interface Task {
}
}
What if queue is already empty? Code will swallow first exception, then retry - and wait forever?
I thought main idea of interruption is cancellation of task if it stuck on some blocking method like Thread.sleep, BlockingQueue.take(), etc.
There is similar question What is the point of restoring the interrupted status in JCIP listing 7.7? , but I don't have enough reputation to post a comment
The point of interruption is not cancellation, the two should be separate when you are thinking about interruption logic. Interruption can be used for cancellation, but as in the sample above, it can also be ignored as well.
It could be that the task returned by getNextTask(...) is so important that the thread cannot afford to exit when interrupted. Therefore, the thread will remain blocked until a task is available in the queue, unless the program completely dies or encounters a catastrophic error.
Again, this is not waiting indefinitely, only until there is a task available. What makes this sample important is that it contains a boolean check when returning, which will pass the interruption to the calling thread. That way, when the thread finally unblocks, an interruption can be checked for it to exit if necessary.
queue.take() will wait until there is something to take. Nothing is throwing an InterruptedExcpetion so the catch block won't execute. You will remain in the try block until something is added to the que or you throw an interupted exception.
Thread.currentThread().interrupt(), unless I am wrong, will not do much, because your code is single threaded right now, and that single thread is already out of the try block if it is in the finally block.
Here is an example of how to use interrupt:
public class StoppingThreads implements Runnable
{
public static void main(String[] args)
{
Thread t0 = new Thread(new StoppingThreads());
t0.start();
Thread t1= new Thread(new StoppingThreads());
t1.start();
Thread t2 = new Thread(new StoppingThreads());
t2.start();
Thread t3 = new Thread(new StoppingThreads());
t3.start();
Thread t4 = new Thread(new StoppingThreads());
t4.start();
System.out.println("All threads started");
t0.interrupt();
t1.interrupt();
}
#Override
public void run()
{
try {
Thread.sleep(5000);
} catch (InterruptedException ex) {
}
System.out.println(Thread.currentThread().getName() + " Finished");
}
}

What is the reason for interrupting the thread in the catch clause of InterruptedException?

I'm reading J. Bloch's Effective Java and now I'm at the section which explains about Concurrency. The writer has provided the following example (Some modifications were applied to make it simpler):
Runnable action;
//...
executor.execute(new Runnable() {
public void run() {
ready.countDown();
try {
start.await();
action.run();
} catch (InterruptedException e) {
Thread.currentThread().interrupt(); // <------- Here
} finally {
done.countDown();
}
}
});
It's not clear that why we interrupt the Thread that already was interrupted? Couldn't you get a little explanation about what kind of troubles we may run into if we omit such interrupting?
Yes, it's right.
When an InterruptedException is thrown from a blocking method, the interrupt flag is cleared.
The right thing to do is to reset the interrupt flag (i.e. interrupt again) and stop running ASAP. Resetting the interrupt flag is necessary to let the executor (or any other calling code) know that the thread has been interrupted, and thus allow it to stop running.

Stopping a Thread / Threads calls interrupt on itself after crash?

I am currently running a Thread from a Service to do some background work.
Now there is the possibility that the Thread crashes or I want to
interrupt the thread from the Service. So how am I supposed to:
stop the Thread realiable, (hard)
catch exceptions and call the Service about the crash
handle InterruptedException if interrupted while sleep()
is Thread.isInterrupted a good way to detect if the Thread stopped?
What I have done so far is the following:
#Override
public void run() {
try {
while (!Thread.currentThread().isInterrupted()) {
doMyBackgroundWork();
sleep();
}
}catch(Exception e){
ExceptionHandler.logAndSendException(e);
Thread.currentThread().interrupt();
if(crashedListener != null){
crashedListener.onThreadCrashed();
}
}
LOG.i("Thread stops now.");
}
private void sleep() {
try {
sleep(frequency);
} catch (InterruptedException e) {
//what to do here? it can happen because I stopped it myself
}
}
So at first I am running my Thread until it gets interrupted.
If any exception occurs, I want to start a new Thread, therefore
my Service implements a listener interface and I call it, once an
Exception is thrown. I know that catching everything is discouraged,
but I need to know if the Thread stops, without polling Thread.isAlive()
all the time.
Additionally to my four questions above:
is my code reliable and does what I need?
is it ok to call interrupt on the Thread itself?
Thanks!
You are not actually interrupting your own thread because the catch block is outside of the while loop. Therefore, any exception would stop execution immediately.
Interruption is essentially just a request (usually from another thread) to stop doing what you are doing. The thread is free to ignore it and keep doing what it is doing. Normally you have to throw an exception in response to an interrupt, or stop execution some other way such as just breaking from the loop (you need this around the //what to do here? comment). It so happens that some library methods are "responsive to interruption" meaning they will throw an exception if the thread is ever interrupted, such as Thread.sleep(), which you will most likely have in your sleep call.
I recommend picking Java Concurrency In Practice. Among the excellent concurrency material, there is a chapter on interrupts which is very helpful.
EDIT:
I would remove the code where you interrupt your own thread. You will also need to rethrow the InterruptedException as a runtime exception to get out of the execution loop. Usually people will create a new Exception that extends RuntimeException that is something like MyInterruptedException. You can then add it to the catch block around your loop so that you know when the thread was interrupted vs execution failed.
As a general example you can do something like this:
public void run() {
try {
while (true) {
// check for interrupts in the loop, or somewhere in the work method
if (Thread.interrupted()) {
throw new MyInterruptedException("Important thread interrupted.");
}
doMyBackgroundWork();
sleep();
}
}
catch(Exception e){
ExceptionHandler.logAndSendException(e);
if(crashedListener != null){
crashedListener.onThreadCrashed();
}
}
catch(MyInterruptedException i) {
LOG.i("Execution stopping because of interrupt.");
}
}
private void sleep() {
try {
sleep(frequency);
} catch (InterruptedException e) {
throw new MyInterrptedException(e);
}
}
we have a nice and effective method called stop()(Thread.stop(void):void) which is deprecated, but it works and it's lovely.
Note that stop() throws ThreadDeath at the target thread which is not an exception(and it could any other throwable too), but an Error, so your code will not catch any signal about this.
public void run() {
try {
while (<<using_a_volatile_bool_type_is_better>>) {
...
}
}catch(Throwable t){/**/}/*use throwable instead of exception.*/}
}
Beside dear friend stop() we also have pause() method too, and it really pauses the target thread.
Not just one solution out there, but if it's really critical to keep thread run and run the emergency(or itself) just after any crash, you may run it as a separately app/process, plus get progress status(if any) that ensures you the target thread/app is not freezed(blocked,...)

Better way to signal other thread to stop?

Started several worker threads , need to notify them to stop. Since some of the threads will sleep for a while before next round of working, need a way which can notify them even when they are sleeping.
If it was Windows programming I could use Event and wait functions. In Java I am doing this by using a CountDownLatch object which count is 1. It works but don't feel elegant, especially I have to check the count value to see if need to exit :
run(){
while(countDownLatch.count()>0){
//working
// ...
countDownLatch.wait(60,TimeUnit.SECONDS);
}
}
Semaphore is another choice, but also don't feel very right. I am wondering is there any better way to do this? Thank you.
Best approach is to interrupt() the worker thread.
Thread t = new Thread(new Runnable(){
#Override
public void run(){
while(!Thread.currentThread().isInterrupted()){
//do stuff
try{
Thread.sleep(TIME_TO_SLEEP);
}catch(InterruptedException e){
Thread.currentThread().interrupt(); //propagate interrupt
}
}
}
});
t.start();
And as long as you have a reference to t, all that is required to "stop" t is to invoke t.interrupt().
Use the builtin thread interruption framework. To stop a worker thread call workerThread.interrupt() this will cause certain methods (like Thread.sleep()) to throw an interrupted exception. If your threads don't call interruptable methods then you need to check the interrupted status.
In the worker thread:
run() {
try {
while(true) {
//do some work
Thread.sleep(60000);
}
}
catch(InterruptedException e) {
//told to stop working
}
}
Good way is to interrupt() threads, and inside thread make cycle like
try {
while (!Thread.interrupted()) {
...
}
} catch (InterruptedException e) {
// if interrupted in sleep
}
Keep in mind both cases when do interrupt:
if you sleep or wait then InterruptedException will be thrown;
in other cases interrupted flag will be set for the thread which you have to check yourself.
To have a pool of threads I would use the ExecutorService or a ScheduledExecutorService for delayed/periodic tasks.
When you want the workers to stop you can use
executorService.shutdown();
The other best approach would be to use interrupt( ) method.
E.g Here's how a thread uses this information to determine whether or not it should terminate :
public class TestAgain extends Thread {
// ...
// ...
public void run( ) {
while (!isInterrupted( )) {
// ...
}
}
}

Calling Thread.sleep() with *interrupted status* set?

The Java documentation is not clear on this point. What happens if you call interrupt on a Thread before a call to Thread.sleep():
//interrupt reaches Thread here
try {
Thread.sleep(3000);
} catch (InterruptedException e) {
return;
}
Will the InterruptedException be thrown?
Please point to relevant documentation.
Yes, it will throw an exception. According to the javadoc for Thread.sleep, the method:
Throws:
InterruptedException - if any thread has interrupted the current thread. The interrupted status of the current thread is cleared when this exception is thrown.
The 'has' in this case is an informal way of referring to the interrupted status. It's a shame that it is informal - if there's somewhere a spec should be precise and unambiguous, well, it's everywhere, but it's the threading primitives above all.
The way the interrupted status mechanism works in general is if that a thread receives an interruption while it's not interruptible (because it's running), then the interruption is essentially made to wait until the thread is interrupted, at which point it swoops in an causes an InterruptedException. This is an example of that mechanism.
A thread can be interrupted at any point in time, but it won't have any effect until that thread specifically checks its interrupted state with Thread.currentThread().isInterrupted() or when it reaches, or is already blocked by a call to Thread.sleep(long), Object.wait(long) or other standard JDK methods which throw InterruptedException such as those in the java.nio package. The thread's interrupt status is reset when you catch an InterruptedException or when you explicitly call Thread.interrupted() (see the documentation for that elusive method).
This JavaSpecialists article should explain a bit more about how thread interrupts work and how to deal with them properly.
You can use the following class to test the behavior. In this case, the loop is not interrupted and the thread dies when it gets to the sleep.
public class TestInterrupt{
public static void main(String[] args) throws InterruptedException {
Thread t = new Thread(){
public void run(){
System.out.println("hello");
try {
for (int i = 0 ; i < 1000000; i++){
System.out.print(".");
}
Thread.sleep(10000);
} catch (InterruptedException e) {
System.out.println("interrupted");
e.printStackTrace();
}
}
};
t.start();
Thread.sleep(100);
System.out.println("about to interrupt.");
t.interrupt();
}
}
The docs of InterruptedException seems to suggest that it can be interrupted at other times
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/InterruptedException.html
Thrown when a thread is waiting, sleeping, or otherwise paused for a long time and another thread interrupts it using the interrupt method in class Thread
Also since it is a checked exception, it will only be thrown by methods that declare it. See
http://download.oracle.com/javase/1.4.2/docs/api/java/lang/Thread.html#interrupt()

Categories