I am learning locking mechanism in java and found out some code which was given as a example in the LockSupport class in which the thread interrupting itself by calling interrupt() method. I am very confused that when a thread is already running then why it is interrupting itself.
I also want to clear all of you that I know what happen when the current thread is interrupted inside the catch block but I want to know what happen when running Thread interrupt itself.
code from LockSupport
sample code is here
class FIFOMutex {
private final AtomicBoolean locked = new AtomicBoolean(false);
private final Queue<Thread> waiters = new ConcurrentLinkedQueue<Thread>();
public void lock() {
boolean wasInterrupted = false;
Thread current = Thread.currentThread();
waiters.add(current);
// Block while not first in queue or cannot acquire lock
while (waiters.peek() != current || !locked.compareAndSet(false, true)) {
LockSupport.park(this);
if (Thread.interrupted()) // ignore interrupts while waiting
wasInterrupted = true;
}
waiters.remove();
if (wasInterrupted) // reassert interrupt status on exit
current.interrupt(); // Here it is interrupting the currentThread which
}
public void unlock() {
locked.set(false);
LockSupport.unpark(waiters.peek());
}
}
I want to know what happen when running Thread interrupt itself.
The interrupt flag is set to true nothing else. Nothing magically like triggering an exception or signalling the thread.
If you interrupt another thread which is blocked on a interruptable method, this would trigger that method to throw an InterruptedException.
When you call
Thread.interrupted()
this clears the flag and if you want set it again, you need to use interrupt() to set the flag to true so other code can detect that the thread was interrupted.
A simpler solution is to use Thread.currentThread().isInterrupted() which doesn't clear the flag.
This is because Thread.interrupted() not only checks that the interrupt flag is set on the current thread, it also clears it!
Therefore it is needed to re-enable it.
The better solution here is to use Thread.currentThread().isInterrupted(), whih does not clear the interrupt flag.
And yes, it is only this: a flag. You don't "signal" a thread, in essence. When you receive an interrupted exception, it is because the callee will have detected that the interruption flag was set and thrown this exception (or "bubbled it up" from below). It doesn't happen "automagically".
In other words: in Java, thread interruption is a cooperative process.
What happens is that Thread.interrupted() returns and clears the thread interrupted flag; the code just resets the flag at the end; essentially postponing thread interrupts for a while.
Related
Suppose I have a Runnable instance:
class MyTask implements Runnable {
public void run() {
//some heavy calculation which takes time
Thread.sleep(5000)
//rest code
...
}
}
Then, I use ExecutorService to submit the above task:
ExecutorService service = Executors.newFixedThreadPool(3);
Future<?> task = service.submit(new MyTask());
Now, I can cancel the task by task.cancel(true);. What I have understood is that the task.cancel(true) will interrupt the working thread in which this task is running, like Thread.currentThread().interrupt(). But this only sets a flag to tell that the working thread is interrupted.
My question is: if MyTask Runnable has started running, how actually does future.cancel(true) stops my code in run() continuing executing the rest code? Is there a periodical checking for the working thread's interrupted flag underneath? I mean I don't understand how the code in run() can be canceled by only set the interrupted flag to true.
Future.cancel does not guarantee that your worker code will stop executing. What it does is set the interrupted flag and cause any blocking JDK calls to throw an InterruptedException. Your worker code may choose to rethrow the interrupted exception and periodically check the interrupted flag, in which case the cancel mechanism will work. Otherwise you may choose to swallow InterruptedException and disregard the iterrupted flag, in which case the cancel mechanism will do nothing but set the cancelled flag to true.
See http://www.ibm.com/developerworks/library/j-jtp05236/
There is a method called isInterrupted(), this tells the running code in the thread that it is interrupted by returning a true/false.
This is usually checked by the methods like wait, sleep which you might invoke in the thread.
If however you do not use these methods, then you will have to manually check this method [ isInterrupted() ] to determine whether someone has interrupted your thread.
If by any chance you get a true, you can decide what action to perform (let us say for example: throw a InterruptedException or break from a loop, etc...)
Well, I am trying to understand why the following combination of Thread.currentThread.interrupt() and return is working fine, when I want to terminate a current thread.
Thread.currentThread.interrupt();
return;
I write a small program:
public class Interr implements Runnable {
#Override
public void run() {
for(int i= 0; i<10000;i++){
System.out.println(i);
if(i==500){
Thread.currentThread().interrupt();
return ;
}
}
}
public static void main(String args []){
Thread thread = new Thread(new Interr());
thread.run();
}
}
I know I can also use Thread.currentThread.stop() but it is an unsafe way to terminate a thread. So I tried to use the combination interupt() and return.
It works but I do not undestand why it works.
Any Explanation?
Edit: in the above example, I am the owner of a Thread. Assume, I am not the owner of a thread. Why This combination is working?
You don't need interrupt(). The return is enough to exit run() which will then cause the thread to stop, since it has no more work to do.
No need to call interrupt() from same thread.
interrupt method will be used to interrupt a thread from other thread.
as per java docs.
Interrupts this thread. Unless the current thread is interrupting
itself, which is always permitted, the checkAccess method of this
thread is invoked, which may cause a SecurityException to be thrown.
If this thread is blocked in an invocation of the wait(), wait(long),
or wait(long, int) methods of the Object class, or of the join(),
join(long), join(long, int), sleep(long), or sleep(long, int), methods
of this class, then its interrupt status will be cleared and it will
receive an InterruptedException.
If this thread is blocked in an I/O operation upon an interruptible
channel then the channel will be closed, the thread's interrupt status
will be set, and the thread will receive a ClosedByInterruptException.
If this thread is blocked in a Selector then the thread's interrupt
status will be set and it will return immediately from the selection
operation, possibly with a non-zero value, just as if the selector's
wakeup method were invoked.
If none of the previous conditions hold then this thread's interrupt
status will be set.
Interrupting a thread that is not alive need not have any effect.
So it will send interrupt signal to the thread which is in I/O block.
#Override
public void run() {
while (true) {
}
}
if a thread has implementation like that , it wont interrupt even after calling this method.
Actually in the code you posted the reason the thread stops is because you called return.
As per the documentation, calling Thread.interrupt() does nothing more than set a flag on the thread you're calling it on. The owner of the thread checks the flag and must find a way to stop what it is doing.
I'm reading this book, (O'Reillys Java Threads 3rd ed., which for now has very bad explanations), and I have encountered this code:
//in RandomCharacterGenerator class
public void run( ) {
while (!isInterrupted()) {
nextCharacter( );
try {
Thread.sleep(getPauseTime( ));
} catch (InterruptedException ie) {
return;
}
}
}
And the following explanation (producer is the instance of upper class in the main thread):
producer.interrupt( );
If the main thread executes this statement while the RandomCharacterGenerator thread is sleeping, the RandomCharacterGenerator thread gets the interrupted exception and immediately returns from the run() method. Otherwise, when the character-feeding thread next gets to the top of its loop, it sees that the interrupted flag has been set and returns from its run() method then. Either way, the random character generator thread completes its task.
Note that this technique does not completely eliminate the possibility that we sleep for some amount of time after the thread is asked to stop. It's possible for the main thread to call the interrupt() method just after the RandomCharacterGenerator has called the isInterrupted() method. The character-reading thread still executes the sleep() method, which won't be interrupted (since the main thread has already completed the interrupt() method). This is another example of a race condition that we solve in the next chapter. Since the race condition in this case is benign (it just means we sleep one more time than we'd like), this is sufficient for our purposes.
Second paragraph is completely unclear to me. My first question is: How can we sleep one more cycle? If we interrupt the thread when sleeping it goes out of run, if we interrupt before sleep it will interrupt sleep as soon as it starts sleeping (I tested that, and I think that's true? Am I right), if we interrupt after sleep it will brake the loop.
Second question: In this example (this is the whole code from the book) is the check in loop completely unnecessary, and can it stand while (true) with the same outcome, so that first paragraph about the top of the loop is complete nonsense?
The book is wrong. Interrupting the thread before it sleeps will make the sleep() method throw an InterruptedException immediately.
Quote from Java Concurrency in Practice:
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.
(emphasis mine)
In this particular example, using while(true) would lead to the same effect. But in other cases, if the loop never calls an interruptible method, or if you want to exit as soon as possible, you'll have to regularly check if the thread is interrupted to be able to detect the interruption.
The book believes you will spend an extra cycle in the following case:
RandomCharacterGenerator -> isInterrupted = false;
Main -> interrupt()
RandomCharacterGenerator -> runs through code
RandomCharacterGenerator -> sleeps
RandomCharacterGenerator -> isInterrupted = true
It actually will interrupt on the sleep, but the thing it is trying to get at that is important is that you may run through the code one more time after calling interrupt()
Suppose during my running I would like to shutdown a single thread gracefully!
I don't want to use Thread.stop() nor Thread.destroy() due to their unsafe behavior.
Note: I'm familiar with using ExecutorService.shutdown() option.
But I would like to know the other way to implement.
The standard way to stop a thread is to call thread.interrupt();. To make it work, you need to make sure you thread responds to interruption, for example:
Thread t = new Thread(new Runnable() { public void run {
while(!Thread.currentThread().isInterrupted()) {
//your code here
}
}});
t.start();
t.interrupt();
This only works if the condition is checked regularly. Note that you can delegate the interruption mechanism to interruptible methods (typically I/O, blocking queues, sleep/wait provide methods that can block until they are interrupted).
Note: In this example, you can also use:
while(!interrupted()) {
//your code here
}
interrupted() does the same thing as Thread.currentThread().isInterrupted() except that the interrupted flag is reset. Since it is your thread, it does not matter.
You could have isStopped()flag in your code. And the running thread should regularly check this flag to see if it should stop. Note that stopping a thread gracefully requires the running code to be written in a way that allows stopping.
You can take a look at this question for some more detailed answers
You have to make the run() method of the thread terminate for some reason. How you achieve this depends on what the thread does.
If the thread is looping, you can stop it by raising a flag (checked by the condition of the loop).
If the thread is waiting over a Socket or any other stream, just close the stream.
If the thread is blocked on a call that can throw an InterruptedException, you can interrupt() the thread and ignore the exception.
If the thread is consuming the elements of a blocking queue, use the poison pill method, which means putting on the queue an element that just means "stop looping".
If you have a loop inside your run() method of your Thread then one option would be that your loop checks for the value of a flag on every iteration.
You can set the flag from outside the code, such as your thread would stop executing before starting the next iteration.
Could you explain what java.lang.Thread.interrupt() does when invoked?
Thread.interrupt() sets the interrupted status/flag of the target thread. Then code running in that target thread MAY poll the interrupted status and handle it appropriately. Some methods that block such as Object.wait() may consume the interrupted status immediately and throw an appropriate exception (usually InterruptedException)
Interruption in Java is not pre-emptive. Put another way both threads have to cooperate in order to process the interrupt properly. If the target thread does not poll the interrupted status the interrupt is effectively ignored.
Polling occurs via the Thread.interrupted() method which returns the current thread's interrupted status AND clears that interrupt flag. Usually the thread might then do something such as throw InterruptedException.
EDIT (from Thilo comments): Some API methods have built in interrupt handling. Of the top of my head this includes.
Object.wait(), Thread.sleep(), and Thread.join()
Most java.util.concurrent structures
Java NIO (but not java.io) and it does NOT use InterruptedException, instead using ClosedByInterruptException.
EDIT (from #thomas-pornin's answer to exactly same question for completeness)
Thread interruption is a gentle way to nudge a thread. It is used to give threads a chance to exit cleanly, as opposed to Thread.stop() that is more like shooting the thread with an assault rifle.
What is interrupt ?
An interrupt is an indication to a
thread that it should stop what it is
doing and do something else. It's up
to the programmer to decide exactly
how a thread responds to an interrupt,
but it is very common for the thread
to terminate.
How is it implemented ?
The interrupt mechanism is implemented
using an internal flag known as the
interrupt status. Invoking
Thread.interrupt sets this flag. When
a thread checks for an interrupt by
invoking the static method
Thread.interrupted, interrupt status
is cleared. The non-static
Thread.isInterrupted, which is used by
one thread to query the interrupt
status of another, does not change the
interrupt status flag.
Quote from Thread.interrupt() API:
Interrupts this thread. First the
checkAccess method of this thread is
invoked, which may cause a
SecurityException to be thrown.
If this thread is blocked in an
invocation of the wait(), wait(long),
or wait(long, int) methods of the
Object class, or of the join(),
join(long), join(long, int),
sleep(long), or sleep(long, int),
methods of this class, then its
interrupt status will be cleared and
it will receive an
InterruptedException.
If this thread is blocked in an I/O
operation upon an interruptible
channel then the channel will be
closed, the thread's interrupt status
will be set, and the thread will
receive a ClosedByInterruptException.
If this thread is blocked in a
Selector then the thread's interrupt
status will be set and it will return
immediately from the selection
operation, possibly with a non-zero
value, just as if the selector's
wakeup method were invoked.
If none of the previous conditions
hold then this thread's interrupt
status will be set.
Check this out for complete understanding about same :
http://download.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
If the targeted thread has been waiting (by calling wait(), or some other related methods that essentially do the same thing, such as sleep()), it will be interrupted, meaning that it stops waiting for what it was waiting for and receive an InterruptedException instead.
It is completely up to the thread itself (the code that called wait()) to decide what to do in this situation. It does not automatically terminate the thread.
It is sometimes used in combination with a termination flag. When interrupted, the thread could check this flag, and then shut itself down. But again, this is just a convention.
For completeness, in addition to the other answers, if the thread is interrupted before it blocks on Object.wait(..) or Thread.sleep(..) etc., this is equivalent to it being interrupted immediately upon blocking on that method, as the following example shows.
public class InterruptTest {
public static void main(String[] args) {
Thread.currentThread().interrupt();
printInterrupted(1);
Object o = new Object();
try {
synchronized (o) {
printInterrupted(2);
System.out.printf("A Time %d\n", System.currentTimeMillis());
o.wait(100);
System.out.printf("B Time %d\n", System.currentTimeMillis());
}
} catch (InterruptedException ie) {
System.out.printf("WAS interrupted\n");
}
System.out.printf("C Time %d\n", System.currentTimeMillis());
printInterrupted(3);
Thread.currentThread().interrupt();
printInterrupted(4);
try {
System.out.printf("D Time %d\n", System.currentTimeMillis());
Thread.sleep(100);
System.out.printf("E Time %d\n", System.currentTimeMillis());
} catch (InterruptedException ie) {
System.out.printf("WAS interrupted\n");
}
System.out.printf("F Time %d\n", System.currentTimeMillis());
printInterrupted(5);
try {
System.out.printf("G Time %d\n", System.currentTimeMillis());
Thread.sleep(100);
System.out.printf("H Time %d\n", System.currentTimeMillis());
} catch (InterruptedException ie) {
System.out.printf("WAS interrupted\n");
}
System.out.printf("I Time %d\n", System.currentTimeMillis());
}
static void printInterrupted(int n) {
System.out.printf("(%d) Am I interrupted? %s\n", n,
Thread.currentThread().isInterrupted() ? "Yes" : "No");
}
}
Output:
$ javac InterruptTest.java
$ java -classpath "." InterruptTest
(1) Am I interrupted? Yes
(2) Am I interrupted? Yes
A Time 1399207408543
WAS interrupted
C Time 1399207408543
(3) Am I interrupted? No
(4) Am I interrupted? Yes
D Time 1399207408544
WAS interrupted
F Time 1399207408544
(5) Am I interrupted? No
G Time 1399207408545
H Time 1399207408668
I Time 1399207408669
Implication: if you loop like the following, and the interrupt occurs at the exact moment when control has left Thread.sleep(..) and is going around the loop, the exception is still going to occur. So it is perfectly safe to rely on the InterruptedException being reliably thrown after the thread has been interrupted:
while (true) {
try {
Thread.sleep(10);
} catch (InterruptedException ie) {
break;
}
}
Thread interruption is based on flag interrupt status.
For every thread default value of interrupt status is set to false.
Whenever interrupt() method is called on thread, interrupt status is set to true.
If interrupt status = true (interrupt() already called on thread),
that particular thread cannot go to sleep. If sleep is called on that thread interrupted exception is thrown. After throwing exception again flag is set to false.
If thread is already sleeping and interrupt() is called, thread will come out of sleeping state and throw interrupted Exception.
Thread.interrupt() sets the interrupted status/flag of the target thread to true which when checked using Thread.interrupted() can help in stopping the endless thread. Refer http://www.yegor256.com/2015/10/20/interrupted-exception.html
An interrupt is an indication to a thread that it should stop what it is doing and do something else. It's up to the programmer to decide exactly how a thread responds to an interrupt, but it is very common for the thread to terminate.
A very good referance: https://docs.oracle.com/javase/tutorial/essential/concurrency/interrupt.html
Thread.interrupt() method sets internal 'interrupt status' flag. Usually that flag is checked by Thread.interrupted() method.
By convention, any method that exists via InterruptedException have to clear interrupt status flag.
public void interrupt()
Interrupts this thread.
Unless the current thread is interrupting itself, which is always permitted, the checkAccess method of this thread is invoked, which may cause a SecurityException to be thrown.
If this thread is blocked in an invocation of the wait(), wait(long), or wait(long, int) methods of the Object class, or of the join(), join(long), join(long, int), sleep(long), or sleep(long, int), methods of this class, then its interrupt status will be cleared and it will receive an InterruptedException.
If this thread is blocked in an I/O operation upon an interruptible channel then the channel will be closed, the thread's interrupt status will be set, and the thread will receive a ClosedByInterruptException.
If this thread is blocked in a Selector then the thread's interrupt status will be set and it will return immediately from the selection operation, possibly with a non-zero value, just as if the selector's wakeup method were invoked.
If none of the previous conditions hold then this thread's interrupt status will be set.
Interrupting a thread that is not alive need not have any effect.
Throws:
SecurityException - if the current thread cannot modify this thread
I want to add one or two things to the above answers.
One thing to remember is that, calling on the interrupt method does not always cause InterruptedException. So, the implementing code should periodically check for the interrupt status and take appropriate actions.
Thread.currentThread().isInterrupted() can also be used to check the interrupt status of a thread. Unlike the Thread.interrupted() method, it does not clear the interrupt status.