A thread opens a resource, which is a blocking operation. If and once it succeeded, the thread is required to close it again, which again is blocking but always succeeds in finite time.
It is possible to use a flag (let's call it hasResource), which cannot be synchronized with other threads in any way, to indicate that the thread does not want to be interrupted. No other synchronization is allowed at all.
Is the following a safe way to handle this scenario?
#Override // we're subclassing Thread
public void run () {
try {
while (!interrupted ()) {
blockingOpen ();
// glitch possibility in this line
hasResource = true;
blockingClose ();
hasResource = false;
}
}
catch (final InterruptedException e) {
interrupt ();
}
}
In particular, does this ensure that the thread will no be interrupted while it has the resource?
As far as I can tell, there is only one window of error opportunity, which is right after the Open and before setting the flag. However, it seems this would not lead to leaking the resource, but to accidentally ignoring the interrupt request. Is it possible to prevent that?
The original code is in fact correct. Setting the bool flag is not a problem, even though the question mistakenly suggests it could be. There are two points to be considered for this to be clear:
Firstly, the line itself cannot cause an error. If the Open succeeded, the flag will be set - always. Not even a StackOverflow or OutOfMemory can reasonably occur here.
Secondly, if interrupt() is called while no interruptible code (e.g. a sleep) is executed, then the interrupted flag will be set. The next time any interruptible code begins execution, this flag will be checked, and instead of running the code, an Interrupted exception will be thrown.
Thus, the original code works indeed as intended.
It is possible to use a flag (let's call it hasResource), which cannot be synchronized with other threads in any way, to indicate that the thread does not want to be interrupted. No other synchronization is allowed at all.
No it isn't.
does this ensure that the thread will no be interrupted while it has the resource?
No. If hasResource is volatile and all your other threads know about hasResource and observe it, then you've inhibited yourself from calling Thread.interrupt(), but you haven't inhibited Java from doing so.
Why your application threads would be interrupting each other is another question. Never used this feature in 20 years.
Related
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.
"boolean cancel(boolean mayInterruptIfRunning) 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"
https://docs.oracle.com/javase/7/docs/api/java/util/concurrent/Future.html#cancel(boolean)
Beside the reasons listed above, what's other reasons it would fail to cancel the task?
Also if the task run the code like below can it be cancelled?
while(true)
{
;
}
The while loop you post would be an example of non-cancelable code, since it does nothing to respond to interruption.
Code that blocks listening to a socket could also fail to handle interruption. Even if code timed out with an InterruptedIOException, if you swallow the exception without setting the interrupt flag then the code can fail to handle interruption.
So TLDR: 1) code that does blocking IO
2) code that is oblivious to how interruption works. Or a combination of both.
There is no good way to terminate a thread in Java actually. You can basically tell a thread to stop, but the thread can be constantly waiting and never gets to read the flag or similar issues. It's actually a kind of complicated issue. So I assume instead of that they just said for "some issue".
Each thread has a special flag that holds the interruption state, it's accessible by means of isInterrupted() method. When someone interrupts a thread, this flag is set to true. That's all. No real interruption happens until the code, executed by this thread, checks this flag and either throws an InterruptedException or just quits the thread execution if it can.
Many methods in the standard library, that are designed to block the current thread, actually check this flag from time to time and throw an InterruptedException when they found the flag is set. For instance, Thread.sleep(), Thread.join(), Object.wait(), Lock.lockInterruptibly() and many others. Hence, when your thread periodically checks this flag explicitly or is blocked by some of the described methods that check it implicitly, it's interruptable. Otherwise, it's not.
So, the thread with an empty loop cannot be interrupted because it doesn't check the interruption status. But adding an interruption state check would fix it:
while (!Thread.currentThread().isInterrupted()) { }
Calling a method responsive to interruptions would also work:
try {
while (true) {
Thread.sleep(timeout);
}
} catch(InterruptedException e) {
// Do nothing, just let the thread exit
}
As many others I have a problem killing my thread without using stop().
I have tried to use volatile on a variable with a while loop in my threads run() routine.
The problem is as far as I can see, that the while loop only checks the variable before every turn. The complex routine Im running takes a long time, and because of that the thread is not terminated immediately.
The thread I want to terminate is a routine that connects to another server and it uses a looooong time. And I want to have an abort button for this. (Terminating the thread). I'll try to explane with some code.
class MyConnectClass{
Thread conThread;
volitile boolean threadTerminator = false;
..some code with connect and abort button..
public void actionPerformed(ActionEvent e) {
String btnName = e.getActionCommand();
if(btnName.equalsIgnoreCase("terminate")){
threadTerminator = true;
conThread.interrupt();
System.out.println("#INFO# USER ABORTED CURRENT OPERATION!");
}else if(btnName.equalsIgnoreCase("connectToServer")){
conThread = new Thread() {
public void run() {
while(threadTerminator == false){
doComplexConnect(); //Uses a loooong time
}
}
}
conThread.start();
}
}
}
How can I kill my "connection" thread instantly?
Thanks.
Java abandoned the stop() approach in Threads a while back because killing a Thread ungracefully caused huge problems in the JVM. From the Javadoc for stop():
Stopping a thread with Thread.stop causes it to unlock all of the monitors that it has locked (as a natural consequence of the unchecked ThreadDeath exception propagating up the stack). If any of the objects previously protected by these monitors were in an inconsistent state, the damaged objects become visible to other threads, potentially resulting in arbitrary behavior. Many uses of stop should be replaced by code that simply modifies some variable to indicate that the target thread should stop running. The target thread should check this variable regularly, and return from its run method in an orderly fashion if the variable indicates that it is to stop running. If the target thread waits for long periods (on a condition variable, for example), the interrupt method should be used to interrupt the wait.
In most cases, it is up to you to check the threadTerminator var whenever it is safe for you to terminate, and handle the thread exit gracefully. See http://docs.oracle.com/javase/6/docs/technotes/guides/concurrency/threadPrimitiveDeprecation.html
If you are doing long I/O, you may be in trouble. Some I/O operations throw an InterruptedException, in which case, you can interrupt the thread, and, if you were in that I/O, that exception will be thrown more or less instantly, and you can abort and cleanup the thread. For this reason, interrupting a thread is preferable to using a special custom threadTerminator variable - it's much more standard. In you main code outside of the I/O, check for interrupted() or isInterrupted() periodically (instead of threadTerminator == false).
If you are doing I/O that doesn't throw InterruptedException, sometimes you can close the Socket or similar, and catch the IOException. And sometimes you are stuck.
Why don't you interrupt the thread and just move on, letting it hang until it finishes? The user could initiate a different action (thread) while the old thread finishes gracefully (which, from what I see you are pretty much doing already btw)
The downside of this that you have trouble when the user starts clicking "connectToServer" a lot (many threads), or when the threads fail to terminate (hanged threads). But maybe it's sufficient for your purpose?
Edit:
It would be simple to implement a mechanism that prevents spawning a new conthread unless "it's good to go" (e.g., use a semaphore).
The tricky part will be deciding whether it's good to open a new connection. You could ask the original thread (I.e. have a isalive() method), or the party you are trying to connect to. Or you could go for a timeout solution. For example, you could let conthread update a timestamp and decide it's dead if the timestamp isn't updated for 1 min etc. The most generally applicable solution would probably be the timeout solution.
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.
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.