Why do InterruptedExceptions clear a thread's interrupted status? - java

If a thread is interrupted while inside Object.wait() or Thread.join(), it throws an InterruptedException, which resets the thread's interrupted status. I. e., if I have a loop like this inside a Runnable.run():
while (!this._workerThread.isInterrupted()) {
// do something
try {
synchronized (this) {
this.wait(this._waitPeriod);
}
} catch (InterruptedException e) {
if (!this._isStopping()) {
this._handleFault(e);
}
}
}
the thread will continue to run after calling interrupt(). This means I have to explicitly break out of the loop by checking for my own stop flag in the loop condition, rethrow the exception, or add a break.
Now, this is not exactly a problem, since this behaviour is well documented and doesn't prevent me from doing anything the way I want. However, I don't seem to understand the concept behind it: Why is a thread not considered interrupted anymore once the exception has been thrown? A similar behaviour also occurs if you get the interrupted status with interrupted() instead of isInterrupted(), then, too, the thread will only appear interrupted once.
Am I doing something unusual here? For example, is it more common to catch the InterruptedException outside the loop?
(Even though I'm not exactly a beginner, I tagged this "beginner", because it seems like a very basic question to me, looking at it.)

The idea is that an interrupt should be handled once. If an explicit InterruptedException did not clear the "interrupt" flag then most catchers for InterruptedException would have to explicitly clear that flag. Conversely, you can "unclear" the flag by self-interruption (Thread.currentThread().interrupt()). Java's designers went for the semantics which would save keystrokes most of the time (i.e. you more often want to clear the flag than keep it set).

It shouldn't. This is an unfortunate design flaw that makes relying on interruptions a risky business, as too often library code will catch InterruptedException without resetting the thread's interrupted flag and carry on. If you happen to signal an interruption to your thread when that particular piece of broken library code is running, when your code regains execution control, it'll be left without a clue that the interruption happened.
This only needs to happen once in any place that you're calling from your code, so in order to be able to interrupt a thread and then use the interrupted bit to control your flow from inside said thread safely, you need to be 100% sure that every piece of code that you're calling does not clear the interrupted bit by mistake. This is very hard to do when libraries are involved, but even if you could account for every single library that you're using in your code, that still doesn't account for buggy JRE code that can make the same mistake.
The fact that it only takes one library (or JRE!) author to not care or think about interruptions in order to break the logic of code that requires it shows that this is the wrong default action to take. Someone who doesn't care about the thread's interrupted bit probably won't bother to reset it after catching InterruptedException – maybe they don't even know it exists! If catching InterruptedException didn't reset the thread's interrupted status, then anyone who did not know about the interrupted bit would automatically "do the right thing" and not cause a problem for any calling code relying on interruptions. Anyone who required clearing it could still do so manually, but then it'd be an explicit action which is much more likely to be correct than an usually unintended side-effect of catching the checked InterruptedException exception. As it stands right now, if you rely on the thread's interrupted bit, anyone down your calling stack that calls Thread.sleep() carelessly can potentially ruin your day.
As a result, most Java multi-threaded code will just duplicate the Java thread interrupt model with an "isRunning" instance field and some mechanism to flip it as a workaround.

Write your code like this and you won't need a flag:
try {
while (!this._workerThread.isInterrupted()) {
// do something
synchronized (this) {
this.wait(this._waitPeriod);
}
// do something else
}
} catch (InterruptedException e) {
// ignore ...
}
As #Boyan points out, it is a bad idea to squash that the interrupt exception ... in general. In this case, the context will determine whether you should squash it (as above), set the interrupt flag (again) or allow the exception to propagate. Among other things, it depends on what the interrupt means in / to your application.

That's because an InterruptedException is considered an abnormal event in which someone else tries to stop a thread from outside it.
When you want to really interrupt a thread you just break its loop condition by setting a boolean or something similar. Or you use .wait() and .notify() from inside that thread. But if you are doing wait() externally:
an exception is thrown to notify that an external thread tried to interrupt me or to make me wait
the thread continues its work because it doesn't take any order from another thread! But the raise of the exception allows you to add special handling and do whatever you want, also effectively stop the thread.

Related

How can I write this with concurrency on Java? [duplicate]

If a thread is interrupted while inside Object.wait() or Thread.join(), it throws an InterruptedException, which resets the thread's interrupted status. I. e., if I have a loop like this inside a Runnable.run():
while (!this._workerThread.isInterrupted()) {
// do something
try {
synchronized (this) {
this.wait(this._waitPeriod);
}
} catch (InterruptedException e) {
if (!this._isStopping()) {
this._handleFault(e);
}
}
}
the thread will continue to run after calling interrupt(). This means I have to explicitly break out of the loop by checking for my own stop flag in the loop condition, rethrow the exception, or add a break.
Now, this is not exactly a problem, since this behaviour is well documented and doesn't prevent me from doing anything the way I want. However, I don't seem to understand the concept behind it: Why is a thread not considered interrupted anymore once the exception has been thrown? A similar behaviour also occurs if you get the interrupted status with interrupted() instead of isInterrupted(), then, too, the thread will only appear interrupted once.
Am I doing something unusual here? For example, is it more common to catch the InterruptedException outside the loop?
(Even though I'm not exactly a beginner, I tagged this "beginner", because it seems like a very basic question to me, looking at it.)
The idea is that an interrupt should be handled once. If an explicit InterruptedException did not clear the "interrupt" flag then most catchers for InterruptedException would have to explicitly clear that flag. Conversely, you can "unclear" the flag by self-interruption (Thread.currentThread().interrupt()). Java's designers went for the semantics which would save keystrokes most of the time (i.e. you more often want to clear the flag than keep it set).
It shouldn't. This is an unfortunate design flaw that makes relying on interruptions a risky business, as too often library code will catch InterruptedException without resetting the thread's interrupted flag and carry on. If you happen to signal an interruption to your thread when that particular piece of broken library code is running, when your code regains execution control, it'll be left without a clue that the interruption happened.
This only needs to happen once in any place that you're calling from your code, so in order to be able to interrupt a thread and then use the interrupted bit to control your flow from inside said thread safely, you need to be 100% sure that every piece of code that you're calling does not clear the interrupted bit by mistake. This is very hard to do when libraries are involved, but even if you could account for every single library that you're using in your code, that still doesn't account for buggy JRE code that can make the same mistake.
The fact that it only takes one library (or JRE!) author to not care or think about interruptions in order to break the logic of code that requires it shows that this is the wrong default action to take. Someone who doesn't care about the thread's interrupted bit probably won't bother to reset it after catching InterruptedException – maybe they don't even know it exists! If catching InterruptedException didn't reset the thread's interrupted status, then anyone who did not know about the interrupted bit would automatically "do the right thing" and not cause a problem for any calling code relying on interruptions. Anyone who required clearing it could still do so manually, but then it'd be an explicit action which is much more likely to be correct than an usually unintended side-effect of catching the checked InterruptedException exception. As it stands right now, if you rely on the thread's interrupted bit, anyone down your calling stack that calls Thread.sleep() carelessly can potentially ruin your day.
As a result, most Java multi-threaded code will just duplicate the Java thread interrupt model with an "isRunning" instance field and some mechanism to flip it as a workaround.
Write your code like this and you won't need a flag:
try {
while (!this._workerThread.isInterrupted()) {
// do something
synchronized (this) {
this.wait(this._waitPeriod);
}
// do something else
}
} catch (InterruptedException e) {
// ignore ...
}
As #Boyan points out, it is a bad idea to squash that the interrupt exception ... in general. In this case, the context will determine whether you should squash it (as above), set the interrupt flag (again) or allow the exception to propagate. Among other things, it depends on what the interrupt means in / to your application.
That's because an InterruptedException is considered an abnormal event in which someone else tries to stop a thread from outside it.
When you want to really interrupt a thread you just break its loop condition by setting a boolean or something similar. Or you use .wait() and .notify() from inside that thread. But if you are doing wait() externally:
an exception is thrown to notify that an external thread tried to interrupt me or to make me wait
the thread continues its work because it doesn't take any order from another thread! But the raise of the exception allows you to add special handling and do whatever you want, also effectively stop the thread.

Ignoring an InterruptedException properly [duplicate]

This question already has answers here:
Why invoke Thread.currentThread.interrupt() in a catch InterruptException block?
(5 answers)
When does Java's Thread.sleep throw InterruptedException?
(8 answers)
Closed 1 year ago.
I am aware that ignoring an InterruptedException is actually a bad practice. But let's assume in my case it is necessary: it is a utils method in a deep place, which is called by different threads. Please also assume it is not possible to rethrow.
If my only option is to tell the system "ok, I will not sleep any further, but I cannot kill this thread myself. I will finish my job and hope that my caller takes care of your interruption request", is this the correct way of doing it?
try {
Thread.sleep(1000);
} catch (InterruptedException e1) {
// ignore
Thread.currentThread().interrupt();
}
Does the method interrupt() do anything else other than resetting the interrupted flag?
Please also assume it is not possible to rethrow.
Impossible; you can always rethrow. throw new RuntimeException("unhandled", e); is never a compile time error - that should be your default choice for "I have no idea what this exceptions means or I cant be bothered to handle it". It's perfectly fine: It ensures that the code will be rolled up properly, you want that to happen when exceptions you can't handle / weren't expecting (heh) occur.
However, in this case, uniquely, 'I did not expect it' also means it cannot possibly happen.
InterruptedException
Note that InterruptedException cannot ever happen unless some code is explicitly doing it. You do not get interrupted when the system is running low on resources and needs you to clean up. You do not get interrupted because some code in java core or any third party library decided to interrupt you for funsies. You do not get interrupted when the user hits CTRL+C, or goes into the task manager and clicks 'end process'.
There is only one way to be interrupted, and it is when some java code running in your JVM process runs: yourThread.interrupt();.
Presumably, there are only two options:
[A] You never do this. The point is moot. Rethrow that thing using throw new RuntimeException(e); - you're writing code that is literally going to never ever run, stop worrying about it.
[B] You invoked interrupt(), explicitly. I assume it wasn't because the cat strolled on the keyboard :) - You had some intent by doing it. So, what is the intent? Whatever you intended to happen, program it in the catch block. The usual options are either to abort a thread entirely (so, just return;), or if you have a loop that sleeps, checks something, sleeps again, etc - to recheck (a poor man's wait/notify setup, in other words), or to re-read some configuration or otherwise re-perform some initialization procedure. It's up to you. There is no described style or rule.
Does the method interrupt() do anything else other than resetting the interrupted flag?
Yes, it returns true or false depending on whether it was up or not. But this is completely pointless. Everything in java that can throw InterruptedException +lowers that flag first_. There is therefore absolutely no point whatsoever in lowering the flag in the catch block - it has already been lowered if you ever get there. You EITHER get the flag raised on you, OR you get an InterruptedException (the flag is there because not everything throws InterruptedEx). Note that if your thread is sleeping due to some sleeping op that is not declared to throws InterruptedException, then it may interrupt or not - it depends on the OS capabilities. For example, if you're waiting for network traffic (e.g. calling read() on an InputStream derived from a java.net.Socket or whatnot), then interrupted the thread may either do nothing at all other than raise the flag, or, it will actually end up shutting down the threadsleep. In that case, the code in that InputStream will lower the flag and ends up throwing some sort of IOException (because it can't throw InterruptedException; InterruptedException is checked, and read() doesn't declare it).
Note that if the flag is raised, and you invoke any method that is specced to throw InterruptedException, said method will act IMMEDIATELY, it never goes to sleep in the first place. It lowers the flag and throws InterruptedException, instantly.
Therefore you rarely need to check the flag - very few threads lack a looping construct and very few threads will chug on for a long time without ever invoking anything that will end up invoking Thread.sleep() or obj.wait() somewhere along the line.
NB: The intent of the interrupted() method is to use it as the sole condition in a busy loop that doesn't otherwise call any code that would throw InterruptedException. e.g.:
while (!Thread.interrupted()) {
doSomethingThatNeverSleeps();
}
that'd be the whole body of your run() method. That will keep running forever and make your CPU fans make the laptop take off, at least until some other code tells the thread to call it a day by invoking .interupt(). As I said, rare that you need this construct, but that's what it is for.

Java - concurrency: LinkedBlockingQueue, "try again if failed"

int capacity = ...
BlockingQueue q = new LinkedBlockingQueue<Element>(capacity);
Now, I do feel mildly ridiculous asking this but I'm not particularly savvy when it comes to java concurrency, so I would appreciate some help with choosing the correct way to enqueue something (and dequeue, actually, but I expect when we cleared up the one, the other will fall into place by itself).
There is, of course
while(!q.offer(e));
But I'm a bit wary of spinning implementations in a multi-threaded environment.
And I can't do
synchronized(q){
while(!q.offer(e))q.wait();
}
either because the wakeup calls will go to internal (private) instances of Condition, meaning this would be a suicide-by-sleeping-pills implementation.
However, I'm also not particularly fond of
try{
q.put(e);
}catch(InterruptedException ex){}
(even though it does seem to be a popular choice in online examples) because although this would do the waiting for me, I know of no reliable way to detect when an exception would force me to try again.
I could do something like
boolean success = false;
do{
try{
q.put(e);
success = true;
}catch(InterruptedException ex){}
}while(!success)
But then I'd end up enqueuing the same element multiple times if the exception takes place in-between the put and the assignment to success.
I could do
boolean success = true;
do{
try{
q.put(e);
}catch(InterruptedException ex){
success = false;
}
}while(!success)
But I remember having read (way back) that you shouldn't rely on exception handling for conditionals (though I can't seem to remember the reason why this is discouraged).
So ... what options do I have? Do I need to spin or is there something more intelligent?
It is not a good practice to catch an InterruptedException as you do since your code won't be responsive to interruption anymore. An InterruptedException is usually thrown by methods that are responsive to interruptions (current Thread being interrupted) such as the methods of type await, wait, join, sleep and many others, this should not be considered as a failure but rather as it really is, a Thread's status change that needs be taken into consideration.
As Brian Goetz explains in Java Concurrency in Practice, I quote:
When your code calls a method that throws InterruptedException, then
your method is a blocking method too, and must have a plan for
responding to interruption. For library code, there are basically two
choices:
Propagate the InterruptedException. This is often the most sensible policy if you can get away with it just propagate the
InterruptedException to your caller. This could involve not catching
InterruptedException, or catching it and throwing it again after
performing some brief activity-specific cleanup.
Restore the interrupt. Sometimes you cannot throw InterruptedException, for instance when your code is part of a
Runnable. In these situations, you must catch InterruptedException
and restore the interrupted status by calling interrupt on the
current thread, so that code higher up the call stack can see that an
interrupt was issued.
So in your case, you should simply use put(E) as it will make the calling thread waits for space to become available if needed and propagate the InterruptedException in order to keep on being responsive to interruptions.
But then I'd end up enqueuing the same element multiple times if the
exception takes place in-between the put and the assignment to
success.
This can simply never happen since an assignment of a boolean will never throw any exceptions (except a NPE in case of an un-boxing). And only methods responsive to interruption can throw such kind of exceptions as explained above which is clearly not the case of an assignment.
The put() implementation would be the correct one, blocking until interrupted or successful. The offer() is a bad idea if all you are doing is spinning (see first comment for disclaimer).
As Nicolas explained, the handling of the InterruptedException is not straightforward and depends a lot on what your other code is doing, but your concern with "if the exception takes place in-between the put and the assignment to success", that can never happen: a blocking call (like put()) can throw that exception, but it cannot occur between put() and the assignment, or at the assignment.
Lastly, there's no need to synchronize on anything. The main idea in many of java.util.concurrent classes is to avoid or abstract away the explicit synchronization.
So a few points from the LinkedBlockingQueue Javadoc:
The put method will only throw exceptions in two circumstances:
The thread is interrupted, in which case you should stop whatever you're doing anyway. See this question for more about InterruptedExceptions.
The element you're inserting is null, which is another bug entirely.
So overall, you can just use put to wait for space to become available. If either of these particular exceptions is thrown, then you shouldn't retry anyway.

Who is calling the Java Thread interrupt() method if I'm not?

I've read and re-read Java Concurrency in Practice, I've read several threads here on the subject, I've read the IBM article Dealing with InterruptedException and yet there's something I'm simply not grasping which I think can be broken down into two questions:
If I'm never ever interrupting other threads myself, what can trigger an InterruptedException?
If I'm never ever interrupting other threads myself using interrupt() (say because I'm using other means to cancel my working threads, like poison pills and while (!cancelled) style loop [as both explained in JCIP]), what does an InterruptedException then mean? What am I supposed to do upon catching one? Shutdown my app?
The Thread interrupt mechanism is the preferred way to get a (cooperating) thread to respond a request to stop what it is doing. Any thread (including the thread itself I think) could call interrupt() on a Thread.
In practice, the normal use-cases for interrupt() involve some kind of framework or manager telling some worker thread to stop what they are doing. If the worker thread is "interrupt aware" it will notice that it has been interrupted via an exception, or by periodically checking its interrupted flag. On noticing that it has been interrupted, a well-behaved thread would abandon what it is doing and end itself.
Assuming the above use-case, your code is likely to be interrupted if it is run within a Java framework or from some worker thread. And when it is interrupted, your code should abandon what it is doing and cause itself to end by the most appropriate means. Depending on how your code was called, this might be done by returning or by throwing some appropriate exception. But it probably should not call System.exit(). (Your application does not necessarily know why it was interrupted, and it certainly does not know if there are other threads that need to be interrupted by the framework.)
On the other hand, if your code is not designed to run under the control of some framework, you could argue that the InterruptedException is an unexpected exception; i.e. a bug. In that case, you should treat the exception as you would other bugs; e.g. wrap it in an unchecked exception, and catch and log it at the same point you deal with other unexpected unchecked exceptions. (Alternatively, your application could simply ignore the interrupt and continue doing what it was doing.)
1) If I'm never ever interrupting other threads myself, what can trigger an InterruptedException?
One example is if your Runnable objects are executed using an ExecutorService and shutdownNow() is called on the service. And in theory, any 3rd-party thread pool or thread management framework could legitimately do something like this.
2) If I'm never ever interrupting other threads myself using interrupt() ... what does an InterruptedException then mean? What am I supposed to do upon catching one? Shutdown my app?
You need analyze the codebase to figure out what is making the interrupt() calls and why. Once you have figured that out, you can work out what >>your<< part of the app needs to do.
Until you know why InterruptedException is being thrown, I would advise treating it as a hard error; e.g. print a stacktrace to the log file and shut down the app. (Obviously, that's not always the right answer ... but the point is that this is "a bug", and it needs to be brought to the attention of the developer / maintainer.)
3) How do I find out who / what is calling interrupt()?
There is no good answer to this. The best I can suggest is to set a breakpoint on the Thread.interrupt() and look at the call stack.
If you decide to integrate your code with other libraries, they can call interrupt() on your code. e.g. if you decide in the future to execute your code within an ExecutorService, then that may force a shutdown via interrupt().
To put it briefly, I would consider not just where your code is running now, but in what context it may run in the future. e.g. are you going to put it in a library ? A container ? How will other people use it ? Are you going to reuse it ?
As others have pointed out, interrupting a thread (actually, interrupting a blocking call) is usually used for purposes of exiting cleanly or cancelling an ongoing activity.
However, you should not treat an InterruptedException alone as a "quit command". Instead, you should think of interrupts as a means to control the running status of threads, much in the same way as Object.notify() does. In the same way that you'd check the current state after waking up from a call to Object.wait() (you don't assume that the wakeup means your wait condition has been satisfied), after being nudged with an interrupt you should check why you were interrupted. There is usually a way to do this. For example, java.util.concurrent.FutureTask has an isCancelled() method.
Code sample:
public void run() {
....
try {
.... // Calls that may block.
} catch (InterruptedException e) {
if (!running) { // Add preferred synchronization here.
return; // Explicit flag says we should stop running.
}
// We were interrupted, but the flag says we're still running.
// It would be wrong to always exit here. The interrupt 'nudge'
// could mean something completely different. For example, it
// could be that the thread was blocking on a read from a particular
// file, and now we should read from a different file.
// Interrupt != quit (not necessarily).
}
....
}
public void stop() {
running = false; // Add preferred synchronization here.
myThread.interrupt();
}
The problem with the question is "I". "I" usually refers to a single instance of a class. I mean by that, that any particular piece of low-level code (class) should not rely upon the implementation of the entire system. Having said that you do have make some "architectural" decisions (like what platform to run on).
Possible unexpected interrupts coming from the JRE are canceled tasks in java.util.concurrent and shutting down applets.
Handling of thread interrupts is usually written incorrectly. Therefore, I suggest the architectural decision to avoid causing interrupts where possible. However, code handling interrupts should always be written correctly. Can't take interrupts out of the platform now.
You could learn this by creating your own thread class (extending java.lang.Thread) and overriding interrupt() method, in which you record the stacktrace into, say, a String field, and then transfer to super.interrupt().
public class MyThread extends Thread {
public volatile String interruptStacktrace; // Temporary field for debugging purpose.
#Override
public void interrupt() {
interruptStacktrace = dumpStack(); // You implement it somehow...
super.interrupt();
}
}
As already mentioned, another library can interrupt your threads. Even if the library doesn't have explicit access to the threads from your code, they can still get the list of threads that are running and interrupt them that way with the following method.
I think I understand why you are a bit confused about interruption. Please consider my answers in line:
If I'm never ever interrupting other threads myself, what can trigger an InterruptedException?
Firstly you may interrupt other threads; I know that in JCiP it is mentioned that you should never interrupt threads you do not own; however, this statement has to be properly understood. What it means is that your code which might be running in any arbitrary thread should not handle interruption because since it is not the owner of the thread it has no clue of its interruption policy. So you may request interruption on other threads, but let its owner take the course of interruption action; it has the interruption policy encapsulated within it, not your task code; at least be courteous to set the interruption flag!
There are many ways why there could be interruptions still, may be timeouts, JVM interrupts etc.
If I'm never ever interrupting other threads myself using interrupt() (say because I'm using other means to cancel my working threads, like poison pills and while (!cancelled) style loop [as both explained in JCIP]), what does an InterruptedException then mean? What am I supposed to do upon catching one? Shutdown my app?
You need to be very careful here; if you own the thread which threw InterruptedException (IE), then you know what to do upon catching it, say you may shutdown your app/service or you may replace this killed thread with a new one! However, if you do not own the thread then upon catching IE either rethrow it higher up the call stack or after doing something (may be logging), reset the interrupted status so that the code which owns this thread, when control reaches it, may learn that the thread was interrupted and hence take actions as it will since only it knows the interruption policy.
Hope this helped.
The InterruptedException says that a routine may be interrupted, but not necessarily that it will be.
If you don't expect the interrupt then you should treat it as you might any other unexpected exception. If it's in a critical section where an unexpected exception could have heinous consequences, it might be best to try and clean up resources and gracefully shutdown (because getting the interrupt signals that your well-engineered application that doesn't rely on interrupts is being used in a way it wasn't designed, and so there must be something wrong). Alternatively, if the code in question is something non-critical or trivial, you might want to ignore (or log) the interrupt and keep going.

Java: Difference in usage between Thread.interrupted() and Thread.isInterrupted()?

Java question: As far as I know, there are two ways to check inside a thread whether the thread received an interrupt signal, Thread.interrupted() and Thread.isInterrupted(), and the only difference between them is that the former resets the internal interrupted flag.
So far, I've always used Thread.isInterrupted() and never had any problems with it. Then again, most tutorials I've seen recommend using Thread.interrupted(). Is there any specific reason for that?
interrupted() is static and checks the current thread. isInterrupted() is an instance method which checks the Thread object that it is called on.
A common error is to call a static method on an instance.
Thread myThread = ...;
if (myThread.interrupted()) {} // WRONG! This might not be checking myThread.
if (myThread.isInterrupted()) {} // Right!
Another difference is that interrupted() also clears the status of the current thread. In other words, if you call it twice in a row and the thread is not interrupted between the two calls, the second call will return false even if the first call returned true.
The Javadocs tell you important things like this; use them often!
If you use interrupted, what you're asking is "Have I been interrupted since the last time I asked?"
isInterrupted tells you whether the thread you call it on is currently interrupted.
The interrupted() method is a class method that always checks the current thread and clears the interruption "flag". In other words, a second call to interrupted() will return false.
The isInterrupted() method is an instance method; it reports the status of the thread on which it is invoked. Also, it does not clear the interruption flag. If the flag is set, it will remain set after calling this method.
There are a lot of idioms surrounding InterruptedException, but the question was about checking the interrupted status explicitly.
My understanding is that isInterrupted (the instance method) should rarely be used—mainly for logging and debugging and the like. It only gives a snapshot of the flag on a given thread, which can be outdated soon afterwards.
The normal idiom is to check interrupted (the static method) if you are writing a task which you want to be cancelable at a certain point where it is not calling something that throws InterruptedException due to a sleep or blocking I/O call or the like. If you see the flag set, you should stop your current computation as quickly as you can, returning early or throwing an exception (perhaps InterruptedException).
So as an example, if your task looks something like
void process(Things[] things) throws InterruptedException {
for (Thing thing : things) {
thing.twiddle(); // this call throws InterruptedException
}
}
then you do not need to do anything else; if someone calls Thread.interrupt on your thread, during the current or next twiddle call an InterruptedException will be thrown up and stop your task.
But what if twiddle does not throw InterruptedException and generally cannot be interrupted in the middle? Say each such call takes 100ms, but things.length might be 100. Then process could be blocked for 10s even if someone is trying to interrupt it, which may be unacceptable in your application. So you can explicitly check for interrupts:
void process(Things[] things) {
if (Thread.interrupted()) {
return;
}
for (Thing thing : things) {
thing.twiddle();
}
}
Here you can see why it is important that interrupted atomically checks and clears the flag: you are using it to acknowledge receipt of a message, that someone has politely requested you stop as soon as possible. (In this case, within about 100ms of the request.) You can also see why this must be a static method, operating on the current thread: it only makes sense in the context of checking whether the surrounding code should be stopped.
Of course if the caller of process is assuming it ran to completion, simply returning as shown here would be misleading. So you might want to make process return the number of things it finished processing, or it might just be more appropriate to throw the exception up:
void process(Things[] things) throws InterruptedException {
if (Thread.interrupted()) {
throw new InterruptedException();
}
for (Thing thing : things) {
thing.twiddle();
}
}
In this case the caller gets a (checked) exception informing them that someone else asked to stop processing in the middle. Usually the caller should just let the exception be thrown up the call stack.
You could also reinterrupt yourself if you were unable to stop your current task yet needed to know that a request to stop it did come in, for example to cut the rest of the work short:
void process(Things[] things) {
boolean twiddleFully = true;
if (twiddleFully && Thread.interrupted()) {
twiddleFully = false;
Thread.currentThread().interrupt();
}
for (Thing thing : things) {
thing.twiddle(twiddleFully);
}
}
Here we can process the remaining things more quickly but still complete the loop, and turn the interrupted flag back on so that our caller can decide to handle it.
Thread interruption in Java is advisory. If you call Thread.interrupt() then it will set the flag and cancel any outstanding IO tasks (which will throw InterruptedException). However it is up to code that is executing in the thread to handle this. Doing so is called implementing the Thread interruption policy.
However because Thread's interrupted state is shared it is important that any such handling be Thread Safe. You don't want some other thread going off and trying to do something with the interrupted flag if you are handling it. For this reason the Thread.interrupted() flag makes this atomic so it is used when you want to say: "If this thread was interrupted then I am going to deal with it). Usually this will involve cleaning up some resources. Once you are done you should probably propogate the interrupted flag so that callers can handle it. You can do this by calling Thread.interrupt again.
Here are a couple of examples of how you might use these methods:
If you were writing your own thread pool, you might want to check the interrupted status on one of the threads that you are managing. In that case, you would call managedThread.isInterrupted() to check it's interrupted status.
If you are writing your own InterruptedException handlers that don't immediately retrigger an equivalent exception via Thread.currentThread().interrupt() (for example, you might have a finally block after your exception handlers), you might want to check whether that thread that you are currently running on has been interrupted via an outside call or InterruptedException. In that case, you would check the boolean value of Thread.interrupted() to check on the status of your current thread.
The second method is really only ever useful to me in situations where I'm afraid that someone has written an exception eater at a lower level that, by extension, has eaten an InterruptedException as well.
interrupted() method is a static method of class thread checks the current thread and clear the interruption "flag".i.e. a second call to interrupted() will return false.
isInterrupted() method is an instance method; it reports the status of the thread on which it is invoked. it does not clear the interruption flag.
If the flag is set, it will remain set after calling this method.
Thread myThread = ...;
if (myThread.interrupted()) {} //error
Thread.interrupted()//right
if (myThread.isInterrupted()) {} // Right
This is a old question and having gone through the answers I feel that there is still some missing information. Here's my attempt to fill in that missing piece of info.
From Java 5 onwards usually you would deal with Threads only indirectly .Infact threads spawned from the java.util.Executor framework are dealt within library methods. These threads often call entities that are of blocking nature like Future.get() . ie get() blocks untill result is available .Now there is a overloaded form of get() that takes a timeout value and calling that method means that the thread wants to wait for a period equal to the timeout for the get () to return a value ,if not that task can be cancelled via Future.cancel(). So these methods deal with interruption seriously in that as soon as they sniff a interruption , they also throw the checked InterruptionException . Hence the callers are forced to handle InterruptionException. Since they already propagate the InterruptedException which conveys the interrupted status , it makes sense for the blocking mehthods to also clear the interrupted status by calling Thread.interrupt(). Otherwise , the contract of InterruptedException is violated.
However , if you are dealing with raw threads which is ofcourse not recommnended now , you should be careful when calling the static method interrupted() because if you call it twice in a row and the thread is not interrupted between the two calls, the second call will return false even if the first call returned true.
Why interrupt?
Interrupting threads in Java is useful when you have a long running task that you now need to stop, or when you have a daemon that you need to turn off, and other examples.
How to interrupt
To interrupt you call interrupt() on the thread. This is a cooperative process, so your code has to be ready for it. Like this:
myThread.interrupt();
Responsible code
Your code's responsibility is to be ready for any interruptions. I'd go so far to say that whenever you have a long running task, that you insert some interrupt ready code like this:
while (... something long...) {
... do something long
if (Thread.interrupted()) {
... stop doing what I'm doing...
}
}
How to stop what I'm doing?
You have several options:
If your you are in Runnable.run() just return or break out of the loop and finish the method.
You may be in some other method deep in the code. It may make sense at that point for that method to throw InterruptedException so you would just do that (leaving the flag cleared).
But maybe deep in your code it doesn't make sense to throw InterruptedException. In that case you should throw some other exception, but before that mark your thread interrupted again so the code that catches knows that an interrupt was in progress. Here's an example:
private void someMethodDeepDown() {
while (.. long running task .. ) {
... do lots of work ...
if (Thread.interrupted()) {
// oh no! an interrupt!
Thread.currentThread().interrupt();
throw new SomeOtherException();
}
}
}
Now the exception can propagate an either terminate the thread or be caught, but the receiving code hopefully notices that an interrupt is in progress.
Should I use isInterrupted() or interrupted()
You should prefer interrupted() because:
Your code should reset the interrupt flag because if you don't the thread you are using could go back to a thread pool with an interrupted state causing problems (of course, that's a bug in the thread pool code, you won't get that behavior if you use Executors.newFixedThreadPool() for example. But other threading code could have it.
As another answer stated, the clearing of the interrupted flag indicates that you've received the message and are taking action. If you leave it on true, the after a while caller can assume you won't respond to it in a timely manner.
Why interrupt() why not some other flag in my code?
Interrupt is the best mechanism for interruption because our code can be ready for it. If we find code that is just catching and ignoring the InterruptExceptions or not checking for interrupted() in its body then we can correct those mistakes and make our code always cleanly interruptible without creating arcane dependencies on non-standard mechanisms in your code.
Unfortunately Joshua Block proposed the opposite in his famous book Effective Java, Second Edition. But I believe enabling the interrupt() method to work as intended is much better.
Doesn't Future.cancel() already handle this?
Future cancel removes the task from the running queue. If your task is already running it won't stop it. So cancel() is a different concept that interrupting. As the Javadocs say:
Attempts to cancel execution of this task. This attempt will fail if
the task has already completed, has already been cancelled, or could
not be cancelled for some other reason. If successful, and this task
has not started when cancel is called, this task should never run. If
the task has already started, then the mayInterruptIfRunning parameter
determines whether the thread executing this task should be
interrupted in an attempt to stop the task.
https://docs.oracle.com/en/java/javase/14/docs/api/java.base/java/util/concurrent/Future.html#cancel(boolean)
But calling it will generate an interrupt if mayInterruptIfRunning is on.

Categories